ACodec.cpp revision 2c9c8cba8562cc3a27532e4cd348912cc78d8d98
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
646258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
647258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
648258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
649054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
650054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
651258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
652258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
653258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
654258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
655258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
65629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
657258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
658258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
659258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
660258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
661258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
66629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
676054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
678054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
679054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
681054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
682054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
685054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
688054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6898ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6901e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
69229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
69774006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
69874006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
699054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
70074006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
70174006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
70274006804065941841883c4b46ee785070164023fJamie Gennis
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
70729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
70874006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
71374006804065941841883c4b46ee785070164023fJamie Gennis
7143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
72674006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
816f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8178ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8181e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
819054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8201e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
82129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
822c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
823c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
856d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
857d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
858d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
860d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
861d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
862d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
863d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
864d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
865d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
868d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
869d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
889349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8942ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8952ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8962ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8972ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
925f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9552944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9562944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9572944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9582944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
965729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
966729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
967c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
968c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
969c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
970c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
97794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
97894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
97994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
98094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
981ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
982ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
985ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
986ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
987774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
988774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
98997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
99097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10255ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1063d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1064308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1065308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1067308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1068308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1069308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1071308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1098308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1103308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1104308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1105308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1106308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1108308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1109308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1110308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1111308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1112308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1113308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1114308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1115308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1116a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1117a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1118a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1119a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1120a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1121a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
112294ee4b708acfa941581160b267afb79192b1d816Chong Zhang
112394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
11242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
11252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
11262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
11272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
11282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
112994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
113072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
113172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
113272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
113372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
113472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
113572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1136308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1137308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1138054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1139054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1140054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1141054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1142054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
114375832930a28fd70f6fc683ed966477ceea810668Robert Shih    mIsConfiguredForAdaptivePlayback = false;
1144054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1145054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1146054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1147054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1148054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1154fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1155fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1156fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1157fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1158fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1159fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1160fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1161fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1162fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1163fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1164fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1165fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1166fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1167fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1168fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1169fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1170fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1171fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1172fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1173fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1174fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1175fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1176fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1177fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1178fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1179fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1180fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
1181fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1182fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1183fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1184fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1185fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1186fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1187fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
118875832930a28fd70f6fc683ed966477ceea810668Robert Shih                mIsConfiguredForAdaptivePlayback = (err == OK);
1189fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1190fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1192054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1193054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1194054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
119575832930a28fd70f6fc683ed966477ceea810668Robert Shih            mIsConfiguredForAdaptivePlayback = true;
1196054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11970167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11980167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11990167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
12000167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
12010167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12020167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1203054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1204054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1205308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
121742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
121842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
121942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
122042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
122142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
122242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
122342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
122442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
122542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
122642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
122742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
122842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
122942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1236aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1237ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1238ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1239ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1240aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1241aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1242aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1243ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1244ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12454471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12464471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1248729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1250729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1252729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1253729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1254729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1255729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1256729de186450f78c099637e1fce743fe531862c52Andreas Huber
1257729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1272516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1273516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1276516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1277516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1278516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1281516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1282516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1283516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1287516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1288516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1290ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1291ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1292ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1293ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1294ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1295ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1296ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1297ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1298ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
129997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
130097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
130197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
130297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
130397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
130497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
130597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
130697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
130797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1309729de186450f78c099637e1fce743fe531862c52Andreas Huber
13104471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13114471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13124471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13134471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13148b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
13158b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
13168b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13179806555d3930be43e11106281dee354820ac1c88Andreas Huber
13188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13218b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13229806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13239806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13249806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13259806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13269806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13279806555d3930be43e11106281dee354820ac1c88Andreas Huber
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1402aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1403aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1404ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1405ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1406ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1407ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1468aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1494ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1495ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1496ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1497ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1498ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
150497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
150597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
150697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
150797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
150897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
150997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
151097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
151197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
151297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
151397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
151497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
151597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
151697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
151797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
151897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
151997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
152097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
152197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
152297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
152397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
152497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
152597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
152697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
152797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
152897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
152997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
153097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
153197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
153297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
153397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
153497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
153597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
153697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
153797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
153897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
153997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
154097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
154197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1588729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1589729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber
1592729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1593729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1594729de186450f78c099637e1fce743fe531862c52Andreas Huber
1595729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1596729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1597729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1598729de186450f78c099637e1fce743fe531862c52Andreas Huber
1599729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1604729de186450f78c099637e1fce743fe531862c52Andreas Huber
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1613729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1614729de186450f78c099637e1fce743fe531862c52Andreas Huber
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1618729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1619729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1620729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1621729de186450f78c099637e1fce743fe531862c52Andreas Huber
16222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
16452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
16462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
16472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1650729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1651729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1652729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber
1656729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1657729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1658729de186450f78c099637e1fce743fe531862c52Andreas Huber
1659729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1660729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1661729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1662729de186450f78c099637e1fce743fe531862c52Andreas Huber
1663729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1664729de186450f78c099637e1fce743fe531862c52Andreas Huber
1665729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1666729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1667729de186450f78c099637e1fce743fe531862c52Andreas Huber
1668729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1669729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1670729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1671729de186450f78c099637e1fce743fe531862c52Andreas Huber
1672729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1673729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1674729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1675729de186450f78c099637e1fce743fe531862c52Andreas Huber
1676729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1677729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1678729de186450f78c099637e1fce743fe531862c52Andreas Huber
1679729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1680729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1681729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1682729de186450f78c099637e1fce743fe531862c52Andreas Huber
1683729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1684729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1685729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1686729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1687729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1688729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1689729de186450f78c099637e1fce743fe531862c52Andreas Huber
1690c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1691c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1692729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1693729de186450f78c099637e1fce743fe531862c52Andreas Huber
1694729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1695729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1696729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1697729de186450f78c099637e1fce743fe531862c52Andreas Huber
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1777e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1778e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
178294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
178394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
200089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
200189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
200289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
200389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
200489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
20150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
20160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
20170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
20180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
20200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
20220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
20250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
20280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
20310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
20340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
20370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
20390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
20400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
20430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
20460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
20470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
20480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
206296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
206396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
206496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
206596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
206696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
206796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
206896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
206996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
207096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
207896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
207996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
214396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
215996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
216096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
223596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
223696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
22470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
22480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
22897c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
22907c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22917c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
233396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
233689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
233789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
233889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
233989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
234089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
234189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
234289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
234389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
234489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
234589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
234689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
237396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
237496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
238796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2466d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2467d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2468d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2469d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2470d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2471d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2472d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2473d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2474d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2475d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2476d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2477d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2478d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2479d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
24807e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
24817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
24827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
24847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
24857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
24887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
24897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
24927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24947e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
24957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
24967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
24977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
25007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
25017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
25027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
25037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
25057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
25067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
25077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
25097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
25127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2513c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2514c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2515c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2516c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
25177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
25197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2520f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
25273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2537f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2557577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
255831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
255931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
256031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
256131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
256231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
256331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
256431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
256531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
256631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
256731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
256831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
256931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
257031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
257131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
257231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
257331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
257431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
257531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
258631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
258731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
258831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2622577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2623577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2624577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2625577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2626577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2627577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
262931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
263031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
263131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
263231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
263331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
263431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
263531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
263631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
263797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
264914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
265214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
265314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
265414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
265514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
265614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
265714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
266714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
266814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
266914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
267214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
267314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
267414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2675e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
26798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
26818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
26829806555d3930be43e11106281dee354820ac1c88Andreas Huber
2683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2686e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2698e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
27059806555d3930be43e11106281dee354820ac1c88Andreas Huber
2706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
274397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
274497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
274597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
274697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
274797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    params.nPortIndex = kPortIndexOutput;
274897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
274997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
275097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
275197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
275297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
275397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
275497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
275597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
275697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
275797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
275897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
275997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
2760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
276431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
276531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
276631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
276731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
276831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
276931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
277031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
277131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
277231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
277331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
277431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
277531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
27765778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2777cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2778cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2779cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2781cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2782cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2783cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2804bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
281787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
281887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
281987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
282087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
282187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
282287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2824bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2825bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2826bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2827bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2828bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2829bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2830bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2831bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2832bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2835bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2836bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2837bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2839bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2840bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2841bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2842bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2843bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2844bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2845bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2846bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2847bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2848bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2849bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2850bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2851bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2852bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2853bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
28541e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
28551e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2856bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2857bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2858bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2859bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2860bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2861bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2862bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2863bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2864bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2865bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2866bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2867bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2868bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2869bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2870bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2871bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2872bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2873bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2874bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2875bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2876bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2877bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2878bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2879bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2880bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2881bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2882bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
28831e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2884bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2885bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2886bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2887bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2888bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2889bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2890bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2891bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2892bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2893bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2894bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2895bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2896bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2897bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
28981e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2899bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2900bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2901bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2902bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2903bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2904bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2905bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2906bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2907bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2908bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2909bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2910bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2911bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2912bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2913bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2914bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2915bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2916bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2917bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2918bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2919bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2920bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2921bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2922bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2923bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2924bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2925bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2926bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2927bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2928bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2931eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2932eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2933eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2934496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2935496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2936496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2937496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2938496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2939496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2940496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2941496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2942496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2943496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2944496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2945496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2946496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2947496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2948496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2949496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2950496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2951496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2952eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2953eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2954eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2955eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2956eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2957eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2958eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2959eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2960eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2961eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2962eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2963eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2964eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2965eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2966eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2967eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2968eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2969eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2970eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2971eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2972f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2977f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
30017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
30027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
30037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
30047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
30057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
30067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
30077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3008ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3009ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3010ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3011ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3012ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3013ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3014ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
30390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
30400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
30410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
30420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
30430af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
30440af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
30450af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
30460af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
30470af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
30480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
30983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3106cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
31123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3113349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3114349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
313096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
313196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
313296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
31722d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31882d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3191a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31932d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3194a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31977fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
31987fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
31997fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
32007fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
32017fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
32027fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
32037fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
32047fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
32053831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
32062d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
32105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
32115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
32125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
32135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3224dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3225dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3226dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3227dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
32465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
32475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
32485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3250d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3251d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3252d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3253d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3259078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
32603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3261078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
32625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
32635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
32645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3265078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
32703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3271078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3273078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3274349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3281d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3282054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3283054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3284054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3285054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3286054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3287054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3288054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3289054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3290054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3291054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3292054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3293054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3294054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3295054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
33085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
33095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
33105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
33115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
33125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
33145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
33155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3317dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
33183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3319dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3320dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3321dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
33223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3323dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3324dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3327349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3328349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3341dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3345625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3346625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3347625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3348625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
33885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
33895778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3390349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3392d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3393d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3394d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3395d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3396d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3397d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3398d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3399d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3400d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3407d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3413054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
34245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
34255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
34265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3427349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
34285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
34295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
34305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
34335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
343531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3436577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3437577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3438577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
34394bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3440577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
34415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3443308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3444308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3445308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3446308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3447308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3448308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3449308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3450308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3451308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
345321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3455496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3456496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
34575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
345821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34608b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
34618b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
34628b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
34635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
34665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
34675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
34682d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
34695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
34765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
34805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
34815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3484dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3514577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3515577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3516577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3517577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3518577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3519577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3520577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
35236aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
352479ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
35285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
35301e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3531cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3532cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3534cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3535cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3566c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
35673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3568c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3569349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3570c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3571c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3573c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3574c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3592f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3596c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3597c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3598ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3599ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3600ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3601ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3602ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3603ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3604ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3605ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3606ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3607ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3608ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3609308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3610ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3613f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
36275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
36285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
36295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3634c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3635c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3637c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3638c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3644c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3654c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3666c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3667c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3668c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3669c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
36705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3672c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
36735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
36745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
36765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3682ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3683ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3684ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3685ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3686ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3687ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3688ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3689ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3690ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3691e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3698e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3699e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3700e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3701afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3702e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3703e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3704e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3705afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3719e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
37231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
37241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
37261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3727e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3728e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3730078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3731078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3732078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
37331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3734078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
37371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
37381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
37391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
37411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
37421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3743c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
37445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
37455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
37485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
37495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3750c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3751cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3752c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3753c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3755ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3759ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3760ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3761ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3762ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
37630167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3764ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3765ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3766afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
37735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
37745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3776c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3777c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3778c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3779c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3783c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3784c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3787c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3788c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3789c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3790c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3791f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3792f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3793f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3794f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3795f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3798a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
379975832930a28fd70f6fc683ed966477ceea810668Robert Shih    mCodec->mIsConfiguredForAdaptivePlayback = false;
3800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3801c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3802c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3803c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3804c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3805c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3806c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3807c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3808c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3809c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3810c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3811c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3812c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3813c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3814c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3815c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3816c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3817c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3818c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3819c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3821c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3823c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3824c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3825c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3826c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3827c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3828c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3831c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3832c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3833c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
38347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
38357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
38367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
38377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
38387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
38397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
38407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3841c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3842c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3843c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3844c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3845c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3846c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3847c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3848c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3851c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3852c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3853c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3854c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3855c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3856c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3857c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3858c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3859c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3860c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3861c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3862c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3863c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3864c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3865c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3866c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3867c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3868c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3869c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3870c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3871c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3872c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3873c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3874c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3875c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3876c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3877c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
38785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
38795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
38805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
38825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
38845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
38855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3889c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3890c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3891c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
38925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3893c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3897386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
38985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
38991173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
39001173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
39011173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
39021173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
39031ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
39041ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
39051ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
39061ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
39115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
39125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
39135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
39145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3915c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3916c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
39175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
39207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
39217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
39227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
39247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
39257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
39277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
39287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
39307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3931a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3932a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3933a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3934a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3935a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3936a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3937a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3938a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3939a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3940a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3941a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3942a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3943a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3944a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3945a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3946a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3947a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
39482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
394994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
395094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
395194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
395294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
395394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
395494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
395594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
395694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
395794ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
395872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
395972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
39602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
39612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
39622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
39632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
39642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
39652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
39662c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
39672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
39682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
39692c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
39702c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
39712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
39722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
39732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
39742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
39752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
39762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
39772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
39782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
39792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
39802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
398172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
398272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
398372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
398472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
398572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
398672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
398772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
398872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
398972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
399072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
399172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
399272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
399394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
399494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
399594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
399694ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
399794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
39987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
39997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
40007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
40017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
40027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
40037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
40047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
40057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
40067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
40077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
40087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
40097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
40107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
40117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4012c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
40135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
40145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
40165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4024f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
40293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4031cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4032cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
403329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4034cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4035cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4036cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
40375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
403891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
403991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4040cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
405572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
40636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
40646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
40666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
40676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
40686463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
40696463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
40706463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
40716463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
40726463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
40736463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
40746463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
40756463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
40766463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
40776463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
40786463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
40796463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
40806463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
40816463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
40826463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4112f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
41173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
412272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4129d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4130d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4131d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4132d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4133d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4134d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4135d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4136d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4137d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4138d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4139d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4140d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4141d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4142d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4143d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4144d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
41456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
41466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
41476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
41486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
41496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
41506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4177f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4178349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4179349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4182f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4187054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4188054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4189054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4190054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4192054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4193054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4194054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4195054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4196054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4197054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
41984dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
41994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
42004dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4201054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4202054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4203054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4219349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4220349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4228054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4229c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4230054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4231054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4232054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4233054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4234054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4236349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
42373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4238349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4239349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4240349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4241349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4242349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4250349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4251349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
42553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4273349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4274349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
42877a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4288d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4289d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4290d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4291d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4292d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4293d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4294d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4295349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4296349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4314496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4315496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4316496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4317496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4318496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4319496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4320496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4321496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4322496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4323496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4324496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4325a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4326a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4327a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4328a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4329a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4330a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4331a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4332a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4333a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4334a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4335a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4336a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4337a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4338a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4339a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4340a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4341a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
43427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
43437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
43446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
43457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
43467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
43477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
43487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
43494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
43504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
43514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
43524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
43534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
43544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
43554dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
43564dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
43574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
43584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
43594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
43604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
43614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4370a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4371a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4372530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4373a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4374a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4375a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4376a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4377a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4378a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4379a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4380a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4381a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4382a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4383a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4384a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4385a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4386a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4387a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4388a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4389a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4390a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4391a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
439272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
439372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
439472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
439572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
439672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
439772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
439872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
439972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
440072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
440172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
440272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
440372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
440472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
440572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
440672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
440772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4408e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4409e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4410e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4411e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4412b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4413b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4414e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4415e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4416e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4417e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4418b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4419b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4420b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4421b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4422b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4423b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4424b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4425b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4426b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4427b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4428b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4429b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4430b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4431b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4432b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4433b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4434e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4435e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4436a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4437a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4438a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
44396507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
44406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
44416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
44426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
44436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
44446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
44456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
44466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
44476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
44486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
44496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4458054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4464349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
446731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
446831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
44703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4489f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4494f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4512349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4514349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
45153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4516349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4517349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
45323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4554cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4555cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4556cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
455729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4558cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4559cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4560cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
45615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4562d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4563755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4564755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4565755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4566755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4567755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4568755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4569755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4570755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4571cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
457831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
45793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4582349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4583349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4584349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4585349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4601f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
46025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
46035778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
46353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
463631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
46375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
463831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
46505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4656349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4657349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4658349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4659349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4660349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4661349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4662349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
46670af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
46695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46770167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
46780167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4706f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
47393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4762f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
47673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
47997a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4800d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4801d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4810e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4811e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4812e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4813e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4814e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4826349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4827349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4828349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4829349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4830349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4831349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4832349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4833349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4834349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
48353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4836349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4837349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4838349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4839349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4840349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4841349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4842349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
48667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
48677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
48687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
48697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4877dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4878dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4879f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4880f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4881f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4882f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4888