ACodec.cpp revision 89869f692c35d0ca914c7de4a1f5ff63c9920634
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
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
37afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
391173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
52f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
75609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
88609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
94609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
162784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
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),
363609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
36854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
371e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
3729806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
374054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
375054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
376a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
37794ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
3782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
3792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
380609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
38172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mCreateInputBuffersSuspended(false) {
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
383c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
396dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
414a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
415a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
416a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
417a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
418a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
419a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4265778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4405778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
444f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4457a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
449f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
456c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
460496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
461496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
462496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
485054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
486054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
487054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
497609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
509ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
510ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
512afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
513afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
514afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
515afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
517308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
518308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
521ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
522ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
523ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
525ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
526308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
527308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
528308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
529308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
536ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
537ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
538ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
551d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
555eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
556eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
558eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
560eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
569054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
570054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
571054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
59029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
595e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
596e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
597e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
598e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
599e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
600e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
601e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
602e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
603e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
604e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
605e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
606e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
607e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
608e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
609e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
610e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
611e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
612e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
613e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
614e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
615e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6173c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6183c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6193c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6205ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6213c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6223c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6243c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
636bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
637bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
638bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
639bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
640bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
641bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
642bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
643bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6503c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
65329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
658258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
659258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
661258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
662258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
66329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
664258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
665258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
666258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
667258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
668e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
669e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
6701faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
6711faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
672e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
673e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
674e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
675e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
676e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
677e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
678e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
6791faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
6801faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
681e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
682e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
683258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
684258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
685258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
686258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
687e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
688e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
689e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
690e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
691e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
692609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
693e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
694e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
695e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
696258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
697258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
698258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
699258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
70429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
709054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
710054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
712054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
713054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
714054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
715054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
717054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
718054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
719054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
720e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
721054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
722609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7288ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7291e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
73129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
73674006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
73774006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
73974006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
74074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
74174006804065941841883c4b46ee785070164023fJamie Gennis
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
746609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
74774006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75174006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
75274006804065941841883c4b46ee785070164023fJamie Gennis
753609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
76574006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
786e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
788609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
807054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
812609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
813054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
816054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
818054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
819054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
821054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
829609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
843609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8471e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
856f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8578ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8581e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8601e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
86129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
862c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
863c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
896d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
897d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
898d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
900d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
901d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
902d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
903d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
904d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
905d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
907054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
908d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
909d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
910054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
911054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
929349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9342ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
9352ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
9362ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
9372ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
965f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9952944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9962944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9972944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9982944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1005729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1006729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1007bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1008bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1009c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1010c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1011c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1012c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
10152472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
10162472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
102194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
102294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
102394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
102494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1025ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1026ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
10272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
10282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1029ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1030ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1031774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1032774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
103397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
103497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10695ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1086e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1087e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1088e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1111308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1112308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1114308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1115308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1116308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1118308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11233a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11243a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11253a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
11263a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
11273a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11283a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11293a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
11303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
11313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
11323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
11343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
11353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1145308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1146308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1147308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1148308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1149308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1150308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1151308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1152308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1153308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1154308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1155308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1156308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1157308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1158308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1159308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1160308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1161308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1162308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1163a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1164a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1165a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1166a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1167a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1168a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
116994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
117094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
11712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
11722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
11732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
11742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
11752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
117694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
117772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
117872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
117972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
118072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
118172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
118272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1183308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1184308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1186054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1187054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1188054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1189054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1191e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1193054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1194054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1195054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1196054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1197054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1198fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1199fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1200fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1201fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1202fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1203fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1204fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1205fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1206fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1207fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1208fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1209fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1210fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1211fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1212fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1213fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1214fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1215fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1216fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1217fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1218fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1219fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1220fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1221fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1222fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1223fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1224fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1225fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1226fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1227fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1228fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
122984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1230fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1231fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1232fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1233fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1234fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1235fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1236fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1238e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                if (err == OK) {
1239e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-width", maxWidth);
1240e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-height", maxHeight);
1241e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("adaptive-playback", true);
1242e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
1243fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1244fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1245054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1246054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1247054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1248054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1249e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            inputFormat->setInt32("adaptive-playback", true);
1250054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
12510167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
12520167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
12530167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
12540167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
12550167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12560167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1257e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1258e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1259e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1260e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1261e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1262e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1263e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1264054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1265054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1266308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
127089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
127242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
127342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
127442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
127542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
127642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
127742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
127842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
127942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
128042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
128142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
128242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
128342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
128442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1291aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1292ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1294ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1295aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1296aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1297aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
13004471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
13014471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1303729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1305729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1307729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1308729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1309729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1310729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1311729de186450f78c099637e1fce743fe531862c52Andreas Huber
1312729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
13192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
13202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
13212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
13222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
13232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
13242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
13252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
13262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1327516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1328516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
13292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
13302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1331516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1332516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1333516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
13352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1336516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1337516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1338516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
13402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
13412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1342516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1343516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
13442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1345ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1346ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1347ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1348ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1349ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1350ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1351ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1352ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1353ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
135497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
135597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
135697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
135797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
135897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
135997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
136097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
136197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
136297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1364729de186450f78c099637e1fce743fe531862c52Andreas Huber
13654471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13664471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13674471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13684471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
13708b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
13718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13729806555d3930be43e11106281dee354820ac1c88Andreas Huber
13738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13758b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13768b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13779806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13789806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13799806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13809806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13819806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13829806555d3930be43e11106281dee354820ac1c88Andreas Huber
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1390e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1391e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1392e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1393e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1394e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1462aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1463aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1464ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1465ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1466ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1467ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1528aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1554ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1555ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1556ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1557ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1558ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
156597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
156697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
156797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
156897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
156997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
157097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
157197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
157297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
157397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
157497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
157597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
157697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
157797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
157897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
157997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
158097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
158197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
158297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
158397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
158497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
158597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
158697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
158797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
158897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
158997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
159097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
159197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
159297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
159397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
159497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
159597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
159697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
159797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
159897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
159997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
160097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
160197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1648729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1649729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1651729de186450f78c099637e1fce743fe531862c52Andreas Huber
1652729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1656729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1657729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1658729de186450f78c099637e1fce743fe531862c52Andreas Huber
1659729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1664729de186450f78c099637e1fce743fe531862c52Andreas Huber
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1668729de186450f78c099637e1fce743fe531862c52Andreas Huber
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1673729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1674729de186450f78c099637e1fce743fe531862c52Andreas Huber
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1678729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1679729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1680729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1681729de186450f78c099637e1fce743fe531862c52Andreas Huber
16822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
17002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
17012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
17022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
17032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
17042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
17052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
17062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
17072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
17082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
17092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1710729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1711729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1712729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1713729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1714729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1715729de186450f78c099637e1fce743fe531862c52Andreas Huber
1716729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1717729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1718729de186450f78c099637e1fce743fe531862c52Andreas Huber
1719729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1720729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1721729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1722729de186450f78c099637e1fce743fe531862c52Andreas Huber
1723729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1724729de186450f78c099637e1fce743fe531862c52Andreas Huber
1725729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1726729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1727729de186450f78c099637e1fce743fe531862c52Andreas Huber
1728729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1729729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1730729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1731729de186450f78c099637e1fce743fe531862c52Andreas Huber
1732729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1733729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1734729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1735729de186450f78c099637e1fce743fe531862c52Andreas Huber
1736729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1737729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1738729de186450f78c099637e1fce743fe531862c52Andreas Huber
1739729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1740729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1741729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1742729de186450f78c099637e1fce743fe531862c52Andreas Huber
1743729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1744729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1745729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1746729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1747729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1748729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1749729de186450f78c099637e1fce743fe531862c52Andreas Huber
1750c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1751c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1752729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1753729de186450f78c099637e1fce743fe531862c52Andreas Huber
1754729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1755729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1756729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1757729de186450f78c099637e1fce743fe531862c52Andreas Huber
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1817f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
18392472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
1840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
184394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
184494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1850e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1851e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1853e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1854e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1855e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1860e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1861e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1862e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1863e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1864e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1865e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1866e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1867e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1868e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1869e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1870e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1871e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
188089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
188189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
188289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
188389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
188489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
188589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
188689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
190289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
190389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
190489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
190589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
190689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
190789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
190889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
190989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
191089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
191189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
191289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
191389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
191489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
1915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2080c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2081c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2082c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2083c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
208489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
208589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
208689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
208789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
208889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
20990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
21000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
21010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
21020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
21040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
21060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
21070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
21080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
21090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
21120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
21150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
21160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
21170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
21180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
21210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
21230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
21240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
21270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
21300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
21310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
21320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
21330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
21340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
214696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
214796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
214896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
214996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
215096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
215196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
215296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
215396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
215496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
216296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
216396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
222796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
224396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
224496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
230396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
232096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
23310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
23320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
23330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
23340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
23350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
23360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
23370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
23380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
23737c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
23747c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
23757c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
241796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2420c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2421c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2422c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2423c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2424c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2425c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2426c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2427c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2428c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2429c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2430c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2431c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2432c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2433c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2434c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2435c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2436c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2437c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2438c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2439c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2440c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2441c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2442c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2443c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2444c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2445c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2446c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2447c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2448c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2449c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2450c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2451c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2452c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2453c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2454c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2455c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2456c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2457c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2458c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2459c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2460c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2461c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2462c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2463c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2464c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2465c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2466c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2467c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2468c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2469c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2470c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2471c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2472c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2473c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2474c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2475c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
247689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
247789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
24784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
24794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
24804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
24814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
24824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
24834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
24844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
24854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
24864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
24874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
24884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
248989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
249089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
249189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
24924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
249389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
249489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
249589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
24964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
24974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
24984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
24994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
25004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
25014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
25034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
25064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
25074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
25084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
25104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
25114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
25134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
25144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
25164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
25174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
25184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
25224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
25234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
25244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
25254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
25264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
25274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
25294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
25304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
25314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
25334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
25344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
25354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
25364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
25374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
25384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
25394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
25414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
25424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
25434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
25464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
25474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
25484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
25494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
25504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
255389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
255489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
255589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
258296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
258396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
259696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2666f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2675d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2676d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2677d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2678d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2679d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2680d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2681d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2682d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2683d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2684d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2685d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2686d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2687d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2688d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
26897e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
26907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
26917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
26937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
26947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
26967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
26977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
26987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
26997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
27017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
27027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27037e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
27047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
27057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
27067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
27077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2708e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
27097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2710c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2711c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2712c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2713c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
27147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
27157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
27167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2717f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2724609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
2725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
275403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
275503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnarvoid ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
275603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
275703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
275803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
275903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
276003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
276103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
276203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
276303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // we need stride and slice-height to be non-zero
276403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
276503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
276603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
276703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        return;
276803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
276903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
277003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
277103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
277203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
277303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
277403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
277503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
277603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
277703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
277803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
277903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        return;
278003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
278103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
278203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
278303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
278403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
278503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
278603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
278703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
278803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
278903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
279003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
279103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
279203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
279303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
279403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
279503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
279603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
279703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
279803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
279903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
280003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
280103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
280203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
280303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
280403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
280503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
280603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
280703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
280803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
280903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
281003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
281103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
281203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
281303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
281403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
281503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
281603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
281703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
281803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
281903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
282003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
282103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
282203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
282303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
282403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
282503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
282603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
282703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
282803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
282903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
283003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
2831e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
2832e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
283331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
283431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
2835e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
283631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
283731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
283831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
283931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
284031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
2842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
284331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
284431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
284531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
284631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
284731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
2849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
2850e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2851e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
2852e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2853e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2854e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
2855e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
2856e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
2857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
285803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
285903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
286003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
286103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
286203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
286303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
286403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
286503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
286603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
286703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    OMX_INDEXTYPE describeColorFormatIndex;
286803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    if (mOMX->getExtensionIndex(
286903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            mNode, "OMX.google.android.index.describeColorFormat",
287003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            &describeColorFormatIndex) ||
287103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        mOMX->getParameter(
287203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            mNode, describeColorFormatIndex,
287303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            &describeParams, sizeof(describeParams))) {
287403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        describeDefaultColorFormat(describeParams);
287503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
287603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
287703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    if (describeParams.sMediaImage.mType != MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN) {
287803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
287903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
288003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
288103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
288203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
288303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
288403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
2885e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
2886e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
2887e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    rect.nPortIndex = kPortIndexOutput;
2888e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2889e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
2890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexConfigCommonOutputCrop,
2891e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
2892e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
2893e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
2894e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
2895e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
2896e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
289731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2898e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
2899e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
2900e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
2901e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
2902e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2904e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2905e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
2906577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2907577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2908577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2909e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
2910e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
2911e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2912e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2913e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
29144730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
29154730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
29164730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
29174730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
29184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
29194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
29204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
29214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
29224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
29234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
29244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
29254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
29264730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
29274730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
29284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
29294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
29304730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
29314730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
29324730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
29334730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
29344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
29354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
29364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
29374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
29384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
29394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
29404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
29414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
29424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
29434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
29444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
29454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
29464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
29474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
29484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
29494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
29504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
29514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
29524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
29534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
29544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
29554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
29564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
29574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
2958e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
2959e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2960e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
2961e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
2962e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
2963e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
2964e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
2965e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
2966e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
2967e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
2968e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2969e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
297031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
2971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2972e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
2973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
297431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
297531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
297631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
297731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
297831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
297931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
298031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
298197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2982e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2983e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2984e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2985e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2986e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2987e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2988e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2989e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2990e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2991e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2992e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
299314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2994e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2995e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
299614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
299714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
299814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
299914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
300014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
300114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3002e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3003e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3004e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3005e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3006e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3007e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3008e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
30098b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3010e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
30118b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
30129806555d3930be43e11106281dee354820ac1c88Andreas Huber
3013e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3014e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3015e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3016e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3017e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3018e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3019e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3020e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3021e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3022e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3023e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3024e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3025e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3026e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3027e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3028e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3029e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3030e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3031e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3032e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3033e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
30359806555d3930be43e11106281dee354820ac1c88Andreas Huber
3036e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3037e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3038e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3039e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3040e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3041e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3042e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3043e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3044e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3045e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3046e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3049e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3051e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3052e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3053e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3054e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3057e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3058e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3060e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3061e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3062e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3063e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3064e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3065e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3066e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3067e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3068e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3069e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3070e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3071e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3072e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3073e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3074e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3075e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3076e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3077e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3078e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3079e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3080e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3081e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3082e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3083e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3084e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3085e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3086e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3087e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3088e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3089e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3090e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3091e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3092e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3093e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3094e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3095e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3096e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3097e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3098e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3099e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3100e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3101e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3102e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3103e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3104e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3105e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3106e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
310797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
310897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
310997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
311097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3111e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
311297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
311397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
311497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
311597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
311697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
311797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
311897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
311997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
312097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
312197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
312297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
312397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3124e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
31258c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
31268c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
31278c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
31288c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
31298c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
31308c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
31318c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
31328c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
31338c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
31348c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
31358c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
31368c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
31378c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
31388c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
31398c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
31408c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
31418c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
31428c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
3143e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3144e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3145e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3146e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
314731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
314831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
314931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
315031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
315131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
315231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
315331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3154e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3155e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3156e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3157e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
3158e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
3159e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3161e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3163e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3164e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3165e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3166e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3167e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3169e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3171e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3172e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3176e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3177e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3178e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3179e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3180e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3181e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3182e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3185e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3187e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3188e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3189e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
319131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
319231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
319331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
319431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
319531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
31965778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3197cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3198d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3199cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3201cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3202cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3203cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3204bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3205bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3206bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3207bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3208bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3209bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3210bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3211bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3212bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3213bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3214bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3215bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3216bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3217bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3218bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3219bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3220bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3221bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3222bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3223bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3224bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3225bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3226bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3227bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3228bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3229bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3230bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3231bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3232bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3233bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3234bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3235bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3236bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
323787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
323887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
323987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
324087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
324187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
324287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3243bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3244bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3245bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3246bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3247bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3248bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3249bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3250bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3251bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3252bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3253bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3254bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3255bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3256bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3257bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3258bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3259bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3260bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3261bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3262bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3263bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3264bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3265bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3266bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3267bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3268bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3269bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3270bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3271bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3272bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3273bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
32741e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
32751e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3276bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3277bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3278bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3279bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3280bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3281bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3282bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3283bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3284bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3285bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3286bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3287bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3288bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3289bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3290bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3291bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3292bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3293bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3294bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3295bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3296bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3297bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3298bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3299bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3300bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3301bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3302bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
33031e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3304bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3305bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3306bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3307bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3308bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3309bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3310bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3311bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3312bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3313bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3314bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3315bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3316bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3317bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
33181e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3319bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3320bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3321bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3322bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3323bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3324bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3325bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3326bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3327bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3328bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3329bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3330bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3331bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3332bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3333bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3334bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3335bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3336bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3337bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3338bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3339bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3340bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3341bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3342bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3343bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3344bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3345bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3346bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3347bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3348bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3351eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3352eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3353eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3354496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3355496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3356496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3357496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3358496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3359496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3360496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3361496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3362496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3363496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3364496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3365496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3366496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3367496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3368496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3369496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3370496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3371496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3372eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3373eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3374eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3375eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3376eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3377eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3378eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3379eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3380eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3381eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3382eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3383eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3384eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3385eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3386eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3387eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3388eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3389eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3390eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3391eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3392f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3397ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3398ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
34227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
34237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
34247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
34257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
34267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
34277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
34287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3429ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3430ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3431ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3432ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3433ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3434ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3435ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34475e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
34485e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
34495e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
34505e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
34515e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
34525e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
34535e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
34545e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3456609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34670af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
34680af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
34690af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
34700af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
34710af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
34720af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
34730af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
34740af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
34750af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
34760af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
34770af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3487609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3495609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3509784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
35213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3529cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
35353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3536349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3537349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3549d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3550d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3551d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3552d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
355396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
355496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
355596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3556d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3557d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3558d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3559d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3560d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3561d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3591d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3592609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
35952d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3598609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3609609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
36102d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3613a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36152d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3616a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36197fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
36207fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
36217fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
36227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
36237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
36247fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
36257fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
36267fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
36273831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
36282d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
36325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
36335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
36345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
36355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
36455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3646dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3647dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3648dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3649dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
36565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
36685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
36695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
36705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3681078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
36823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3683078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3687078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3688d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3689d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3690d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3691d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
36923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3693078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3694d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3695078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3696349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3697d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3698d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3700d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3701d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3702d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3703d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3704054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3705054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3706054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3707054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3708054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3709054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3710054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3712054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3713054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3714054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3715054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3717054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
37305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
37315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
37325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
37335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
37345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
37365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
37375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3739dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
37403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3741dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3742dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3743dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
37443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3745dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3746dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3749349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3750349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3763dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3767625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3768625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3769625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3770625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3807784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
3808609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3810349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3812d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3813d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3814d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3815d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3816d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3817d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3818d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3819d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3820d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3821d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3822d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3823d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3824d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3825d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3826d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3827d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
38445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
3845609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
38465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3847349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
38485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
38495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
38505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
38535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
385531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3856577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3857577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3858577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
38594bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3860577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3863308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3864308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3865308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3866308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3867308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3868308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3869308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3870308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3871308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3872496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
387321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3874496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3875496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3876496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
38775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
387821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38808b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
38818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
38828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
38835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3886d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
3887609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
38882d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
38895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3891609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
38965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
39015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3903d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
3904dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3927609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3933577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3934577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3935577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3936577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3937577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3938577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3939577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
39426aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
394379ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
39446fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3947fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
3948fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
3949fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
3950fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
3951fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
3952fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
3953fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
3954fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
395547aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
3956fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
3957fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
3958fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
3959fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
3960fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
3962fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
3963fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
3964fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
3965fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
3966fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
39691e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3970cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3971cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3973cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3974cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
39766fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
39776fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
39786fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
39796fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4009c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4010609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4011c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4012349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4013c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4014c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4016c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4017c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4035f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4040c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4041ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4042ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4043ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4044ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4045ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4046ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4047ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4048ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4049ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4050ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4051ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4052308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4053ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4054c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4055c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
40695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
40705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
40715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
40725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
40735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4077c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4078c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4079c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
408054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
408154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4082c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4084d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4088c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4094d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4098c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4110c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4112c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4113c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
41145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
41175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
41185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4119c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
41205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4126ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4127ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4128ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4129ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4130ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4131ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4132ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4133ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4134ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4135e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
41365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
41417791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
41425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4143e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4144e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4145e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4146afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4147e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4148e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4149e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4150afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
41535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
41555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
41565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
41595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
41605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
41615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
41625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4163e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
41645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
41661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
41671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
41681065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
41691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
41701065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4171e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4172e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4174078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4175078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4176078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
41771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4178078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
41811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
41827a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
41837a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
41841065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
41851065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
41861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
41871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
41881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4189c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
41917791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
41927791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
41935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
41947791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
41955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4196c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4197cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4199c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4205ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4206ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4207ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4208ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
42090167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4210ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4211ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4212afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
42175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4218d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
42195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
42205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
42215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
42265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4228c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4229c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4230c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4231c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4232c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4233c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4234c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4237f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4238f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4239f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4240f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4241f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4242054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4243054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4244a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4245e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4246e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
4247054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4248c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
425654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
426654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
426754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4268d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
426954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
427054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
427154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4284c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
42857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
42867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
42877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
42887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
42897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
42907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4300c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4301c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4302c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
430554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4315d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4316c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4317c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4318c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4319c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4321c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4322c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4328c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4329c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
43305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
43315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
43325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
43345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
43365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
43375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
43395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4341c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4342c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4343c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
43445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
4345c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
43465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4349386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
43505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
43511173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
43521173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
43531173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
43541173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
43551ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
43561ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
43571ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
43581ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
43635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4364d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4365e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4366e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
43675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
43685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4369c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4370c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
43715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
43725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4374ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
43757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
43767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
43777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4378d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
43797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
43807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
43817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
43827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
43837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
43847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4385a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4386a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4387a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4388a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4389a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4390a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4391a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4392a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4393a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4394a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4395a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4396a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4397a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4398a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4399a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4400a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4401a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
44022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
440394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
440494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
440594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
440694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
440794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
440894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
440994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
441094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
441194ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
441272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
441372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
44142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
44152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
44162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
44172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
44182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
44192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
44202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
44212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
44222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
44232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
44242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
44252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
44262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
44272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
44282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
44292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
44302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
44312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
44322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
44332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
44342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
443572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
443672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
443772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
443872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
443972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
444072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
444172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
444272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
444372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
444472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
444572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
444672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
444794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
444894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
444994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
445094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
445194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
44527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
44537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
44547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
44557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
44567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
44577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
44587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
44597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
44607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
44617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
44627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
44637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
44647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
44657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4466c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
44675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
44685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
44705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4478f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
44833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4485cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4486cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
448729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4488cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4489cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4490cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
44915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
449291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
449391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4494cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
450972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
45176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
45186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
45196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
45206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
45216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
45226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
45236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
45246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
45256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
45266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
45276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
45286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
45296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
45306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
45316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4532d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
45336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
45346463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
45356463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
45366463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4566f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
45713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
457672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4583d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4584d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4585d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4586d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4587d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4588d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4589d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4590d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4591d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4592d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4593d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4594d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4595d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4596d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4597d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4598d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
45996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
46006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
46016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
46026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
46036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
46046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4631f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4632349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4633349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4636f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4637ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4641054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4642054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4643054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4644054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4645054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4646054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4647054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4648054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4649054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4650054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4651054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
46524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
46534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
46544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4673349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4674349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4682054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4683c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4684054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4685054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4686054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4687054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4688054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4690349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
46913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4692349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4693349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4694349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4695349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4696349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46993cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
47013cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
47023cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
47033cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
47043cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
47053cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
47063cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
4707349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4708349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
47123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4727c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
472854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4731349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4732349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
47457a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4746d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4747d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4748d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4749d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4750d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4751d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4752d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4753349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4754349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4772496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4773496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4774496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4775496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4776496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4777496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4778496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4779496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4780496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4781496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4782496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4783a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4784a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4785a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4786a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4787a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4788a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4789a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4790a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4791a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4792a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4793a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4794a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4795a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4796a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4797a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4798a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4799a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
48007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
48017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
48026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
48037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
48047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
48057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
48067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
48074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
48084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
48094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
48104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
48114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
48124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
48134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
48144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
48154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
48164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
48174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
48184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
48194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4828a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4829a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4830530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4831a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4832a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4833a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4834a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4835a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4836a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4837a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4838a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4839a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4840a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4841a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4842a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4843a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4844a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4845a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4846a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4847a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4848a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4849a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
485072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
485172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
485272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
485372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
485472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
485572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
485672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
485772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
485872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
485972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
486072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
486172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
486272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
486372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
486472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
486572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4866e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4867e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4868e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4869e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4870b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4871b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4872e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4873e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4874e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4875e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4876b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4877b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4878b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4879b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4880b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4881b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4882b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4883b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4884b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4885b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4886b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4887b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4888b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4889b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4890b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4891b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4892e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4893e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4894a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4895a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4896a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
48976507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
48986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
4899d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
49006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
49016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
49026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
49036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
49046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
49056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
49066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
49076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
491531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4916054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4922349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
492531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
492631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
49283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4947f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4952f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4970349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4972349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
49733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4974349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4975349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4989f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
49903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5012cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5013cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5014cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
501529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5016cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5017cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5018cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
50195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
5020d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5021755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5022755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5023755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5024755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5025755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5026755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5027755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5028755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5029cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
503631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
50373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5040349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5041349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5042349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5043349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5059f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
50605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
50615778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5092f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
50933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
509431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
50955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
509631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
51085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5114349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5115349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5116349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5117349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5118349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5119349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5120349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
51250af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5126f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
51275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51350167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
51360167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5137bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5138bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5139bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5140bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5141bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5142bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5143bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5155f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5164f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5168f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
51973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5220f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
52253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5230f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
52577a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5258d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5259d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5268e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5269e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5270e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5271e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5272e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5284349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5285349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5286349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5287349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5288609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5289349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5290349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5291349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5292349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
52933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5294349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5295349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5296349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5297349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5298349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5299349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5300349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
53247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
53257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
53267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
53277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5329d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5335dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5336dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5337f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5338f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5339f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5340f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5346