ACodec.cpp revision d8cbe4a024ef54adf043b6ea31fa22271b8b2c51
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),
3719806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
374054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
37694ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
3772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
3782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
379609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
38072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mCreateInputBuffersSuspended(false) {
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
382c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
395dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
407f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
414a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
415a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
416a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
417a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
418a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4195778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4255778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4395778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4447a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
459496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
460496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
461496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
482054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
485054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
486054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
496609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
509ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
511afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
512afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
513afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
514afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
516308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
517308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
521ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
522ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
523ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
525308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
526308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
527308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
528308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
536ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
537ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
550d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
553eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
555eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
557eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
559eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
562eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
569054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
570054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5985ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5993c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6003c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6013c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6023c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6283c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
635054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
638054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
64129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
644258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
645258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
646e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
647e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
6481faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
6491faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
650e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
651e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
652e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
653e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
654e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
655e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
656e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
6571faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
6581faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
659e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
660e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
661258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
662258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
663258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
664258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
665e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
666e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
667e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
668e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
669e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
670609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
671e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
672e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
673e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
674258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
675258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
676258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
677258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
68229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
687054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
688054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
689054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
690054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
691054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
692054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
693054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
694054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
695054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
696054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
697054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
698e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
699054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
700609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
702054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
705054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7068ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
70929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
71474006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
71574006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
71774006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
71874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
71974006804065941841883c4b46ee785070164023fJamie Gennis
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
724609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
72574006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72974006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
73074006804065941841883c4b46ee785070164023fJamie Gennis
731609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
74374006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
764e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
766609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
790609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
807609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
813054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
816054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
821609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8251e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
834f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8358ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8361e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8381e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
83929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
840c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
841c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
874d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
875d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
876d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
878d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
879d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
880d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
881d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
882d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
883d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
886d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
887d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
907349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9122ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
9132ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
9142ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
9152ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
943f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9732944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9742944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9752944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9762944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
983729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
984729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
985bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
986bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
987c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
988c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
989c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
990c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
9932472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
9942472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
99994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
100094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
100194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
100294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1003ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1004ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
10052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
10062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1007ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1008ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1009774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1010774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
101197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
101297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10475ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1064e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1065e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1066e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1082d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1087d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1088d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1091d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1095d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1096308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
11043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
11053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
11083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
11093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
11103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
11123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
11133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1123308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1124308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1125308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1126308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1127308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1128308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1129308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1130308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1131308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1132308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1133308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1134308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1135308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1136308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1137308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1138308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1139308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1140308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1141a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1142a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1143a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1144a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1145a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1146a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
114794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
114894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
11492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
11502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
11512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
11522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
11532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
115494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
115572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
115672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
115772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
115872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
115972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
116072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1161308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1162308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1166054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1167054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1169e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1173054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1174054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1175054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1176fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1177fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1178fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1179fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1180fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1181fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1182fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1183fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1184fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1185fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1186fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1187fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1188fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1189fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1190fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1191fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1192fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1193fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1194fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1195fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1196fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1197fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1198fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1199fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1200fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1201fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1202fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1203fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1204fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1205fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1206fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
120784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1208fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1209fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1210fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1211fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1212fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1213fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1214fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1215e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1216e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                if (err == OK) {
1217e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-width", maxWidth);
1218e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-height", maxHeight);
1219e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("adaptive-playback", true);
1220e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
1221fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1222fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1223054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1224054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1225054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1226054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1227e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            inputFormat->setInt32("adaptive-playback", true);
1228054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
12290167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
12300167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
12310167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
12320167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
12330167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12340167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1235054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1236054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1237308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
124942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
125042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
125142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
125242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
125342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
125442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
125542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
125642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
125742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
125842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
125942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
126042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
126142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1268aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1269ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1270ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1271ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1272aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1273aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1274aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1275ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1276ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12774471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12784471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1280729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1282729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1284729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1285729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1286729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1287729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1288729de186450f78c099637e1fce743fe531862c52Andreas Huber
1289729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
13002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
13012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
13022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
13032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1304516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1305516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
13062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
13072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1308516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1309516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1310516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
13122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1313516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1314516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1315516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
13172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
13182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1319516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1320516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
13212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1322ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1323ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1324ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1325ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1326ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1327ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1328ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1329ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1330ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
133197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
133297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
133397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
133497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
133597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
133697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
133797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
133897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
133997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1341729de186450f78c099637e1fce743fe531862c52Andreas Huber
13424471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13434471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13444471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13454471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13468b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
13478b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
13488b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13499806555d3930be43e11106281dee354820ac1c88Andreas Huber
13508b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13518b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13528b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13538b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13549806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13559806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13569806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13579806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13589806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13599806555d3930be43e11106281dee354820ac1c88Andreas Huber
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1367e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1368e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1369e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1370e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1371e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1439aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1440aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1441ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1442ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1443ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1444ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1505aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
154297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
154397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
154497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
154597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
154697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
154797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
154897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
154997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
155097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
155197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
155297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
155397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
155497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
155597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
155697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
155797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
155897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
155997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
156097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
156197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
156297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
156397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
156497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
156597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
156697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
156797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
156897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
156997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
157097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
157197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
157297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
157397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
157497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
157597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
157697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
157797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
157897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1625729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1626729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1628729de186450f78c099637e1fce743fe531862c52Andreas Huber
1629729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1630729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1631729de186450f78c099637e1fce743fe531862c52Andreas Huber
1632729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1633729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1634729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1635729de186450f78c099637e1fce743fe531862c52Andreas Huber
1636729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1641729de186450f78c099637e1fce743fe531862c52Andreas Huber
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1645729de186450f78c099637e1fce743fe531862c52Andreas Huber
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1650729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1651729de186450f78c099637e1fce743fe531862c52Andreas Huber
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1656729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1657729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1658729de186450f78c099637e1fce743fe531862c52Andreas Huber
16592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
16822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
16832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
16842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1687729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1688729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1689729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1690729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1691729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1692729de186450f78c099637e1fce743fe531862c52Andreas Huber
1693729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1694729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1695729de186450f78c099637e1fce743fe531862c52Andreas Huber
1696729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1697729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1698729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1699729de186450f78c099637e1fce743fe531862c52Andreas Huber
1700729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1701729de186450f78c099637e1fce743fe531862c52Andreas Huber
1702729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1703729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1704729de186450f78c099637e1fce743fe531862c52Andreas Huber
1705729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1706729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1707729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1708729de186450f78c099637e1fce743fe531862c52Andreas Huber
1709729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1710729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1711729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1712729de186450f78c099637e1fce743fe531862c52Andreas Huber
1713729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1714729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1715729de186450f78c099637e1fce743fe531862c52Andreas Huber
1716729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1717729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1718729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1719729de186450f78c099637e1fce743fe531862c52Andreas Huber
1720729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1721729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1722729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1723729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1724729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1725729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1726729de186450f78c099637e1fce743fe531862c52Andreas Huber
1727c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1728c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1729729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1730729de186450f78c099637e1fce743fe531862c52Andreas Huber
1731729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1732729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1733729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1734729de186450f78c099637e1fce743fe531862c52Andreas Huber
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
18162472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
1817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1818e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
182094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
182194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1847e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1848e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1850e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1851e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1853e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2038c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2039c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2040c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2041c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
204289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
204389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
204489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
204589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
204689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
20570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
20580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
20590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
20600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
20620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
20640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
20670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
20700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
20730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
20760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
20790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
20810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
20820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
20850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
20880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
20890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
20900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
210496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
210596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
210696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
210796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
210896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
210996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
211096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
211196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
211296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
212096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
212196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
218596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
220196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
220296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
226196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
227796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
227896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
22890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
22900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
23317c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
23327c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
23337c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
237596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2378c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2379c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2380c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2381c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2382c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2383c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2384c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2385c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2386c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2387c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2388c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2389c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2390c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2391c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2392c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2393c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2394c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2395c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2396c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2397c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2398c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2399c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2400c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2401c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2402c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2403c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2404c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2405c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2406c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2407c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2408c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2409c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2410c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2411c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2412c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2413c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2414c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2415c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2416c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2417c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2418c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2419c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2420c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2421c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2422c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2423c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2424c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2425c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2426c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2427c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2428c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2429c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2430c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2431c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2432c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2433c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
243489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
243589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
24364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
24374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
24384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
24394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
24404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
24414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
24424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
24434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
24444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
24454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
24464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
244789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
244889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
244989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
24504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
245189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
245289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
245389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
24544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
24554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
24564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
24574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
24584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
24594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
24614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
24624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
24634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
24644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
24654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
24664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
24674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
24684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
24694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
24704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
24714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
24724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
24734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
24744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
24754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
24764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
24784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
24794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
24804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
24814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
24824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
24834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
24844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
24854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
24864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
24874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
24884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
24894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
24914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
24924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
24934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
24944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
24954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
24964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
24974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
24994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
25004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
25014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
25044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
25054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
25064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
25074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
25084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
251189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
251289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
251389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
254096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
254196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
255496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2586f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2633d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2634d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2635d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2636d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2637d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2638d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2639d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2640d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2641d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2642d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2643d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2644d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2645d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2646d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
26477e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
26487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
26497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
26517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
26527e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26537e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
26547e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
26557e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
26567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
26577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
26597e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
26607e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26617e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
26627e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
26637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
26647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
26657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2666e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
26677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2668c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2669c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2670c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2671c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
26727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
26737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
26747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2675f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2682609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
2683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2692f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2697f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2712e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
2713e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
271431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
271531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
2716e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
271731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
271831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
271931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
272031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
272131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2722e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
2723e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
272431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
272531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
272631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
272731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
272831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2729e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
2730e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
2731e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2732e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
2733e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2734e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2735e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
2736e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
2737e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
2738e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2739e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
2740e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
2741e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    rect.nPortIndex = kPortIndexOutput;
2742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2743e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
2744e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexConfigCommonOutputCrop,
2745e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
2746e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
2747e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
2748e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
2749e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
2750e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
275131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2752e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
2753e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
2754e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
2755e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
2756e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2757e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2759e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
2760577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2761577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2762577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2763e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
2764e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
2765e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2766e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2767e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
2768e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
2769e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2770e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
2771e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
2772e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
2773e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
2774e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
2775e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
2776e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
2777e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
2778e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
278031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
2781e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2782e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
2783e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
278431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
278531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
278631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
278731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
278831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
278931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
279031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
279197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2796e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
280314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
280614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
280714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
280814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
280914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
281014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
281114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2818e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
28198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
28218b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
28229806555d3930be43e11106281dee354820ac1c88Andreas Huber
2823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2827e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
28459806555d3930be43e11106281dee354820ac1c88Andreas Huber
2846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2847e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2848e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2850e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2851e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2853e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2854e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2855e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2856e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2857e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2860e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2861e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2862e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2863e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2864e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2865e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2866e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2867e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2868e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2869e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2870e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2871e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2877e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2878e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2879e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2881e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2882e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2883e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
2884e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2885e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
2886e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
2887e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2888e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2889e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
2890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
2891e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
2892e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
2893e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2894e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
2895e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
2896e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
2897e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2898e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
2899e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2900e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
2901e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2902e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
2903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
2904e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2905e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2906e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
2907e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
2908e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
2909e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
2910e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2911e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
2912e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
2913e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
2914e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2915e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
2916e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
291797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
291897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
291997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
292097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
2921e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
292297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
292397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
292497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
292597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
292697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
292797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
292897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
292997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
293097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
293197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
293297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
293397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
2934e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
29358c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
29368c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
29378c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
29388c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
29398c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
29408c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
29418c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
29428c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
29438c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
29448c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
29458c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
29468c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
29478c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
29488c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
29498c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
29508c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
29518c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
29528c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
2953e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2954e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
2955e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2956e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
295731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
295831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
295931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
296031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
296131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
296231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
296331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2964e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
2965e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
2966e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2967e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
2968e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
2969e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
2970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
2972e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
2974e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
2975e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2976e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
2977e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
2978e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
2979e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
2980e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
2981e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
2982e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
2983e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
2984e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
2985e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
2986e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
2987e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
2988e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
2989e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
2990e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
2991e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
2992e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
2993e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
2994e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
2995e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
2996e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
2997e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
2998e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
2999e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3000e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
300131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
300231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
300331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
300431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
300531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
30065778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3007cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3008d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3009cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
30105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3011cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3012cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3013cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3014bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3015bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3016bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3017bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3018bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3019bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3020bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3021bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3022bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3023bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3024bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3025bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3026bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3027bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3028bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3029bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3030bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3031bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3032bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3033bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3034bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3035bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3036bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3037bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3038bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3039bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3040bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3041bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3042bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3043bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3044bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3045bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3046bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
304787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
304887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
304987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
305087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
305187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
305287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3053bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3054bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3055bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3056bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3057bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3058bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3059bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3060bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3061bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3062bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3063bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3064bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3065bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3066bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3067bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3068bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3069bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3070bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3071bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3072bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3073bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3074bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3075bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3076bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3077bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3078bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3079bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3080bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3081bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3082bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3083bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
30841e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
30851e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3086bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3087bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3088bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3089bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3090bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3091bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3092bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3093bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3094bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3095bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3096bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3097bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3098bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3099bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3100bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3101bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3102bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3103bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3104bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3105bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3106bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3107bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3108bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3109bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3110bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3111bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3112bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
31131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3114bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3115bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3116bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3117bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3118bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3119bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3120bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3121bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3122bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3123bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3124bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3125bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3126bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3127bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
31281e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3129bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3130bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3131bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3132bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3133bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3134bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3135bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3136bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3137bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3138bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3139bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3140bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3141bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3142bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3143bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3144bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3145bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3146bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3147bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3148bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3149bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3150bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3151bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3152bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3153bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3154bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3155bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3156bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3157bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3158bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3161eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3162eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3163eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3164496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3165496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3166496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3167496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3168496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3169496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3170496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3171496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3172496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3173496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3174496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3175496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3176496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3177496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3178496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3179496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3180496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3181496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3182eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3183eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3184eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3185eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3186eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3187eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3188eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3189eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3190eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3191eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3192eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3193eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3194eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3195eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3196eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3197eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3198eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3199eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3200eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3201eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3202f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3207ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3208ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
32327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
32337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
32347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
32357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
32367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
32377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
32387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3239ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3240ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3241ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3242ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3243ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3245ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32575e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
32585e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
32595e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
32605e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
32615e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
32625e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
32635e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
32645e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3266609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32770af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
32780af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
32790af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
32800af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
32810af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
32820af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
32830af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
32840af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
32850af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
32860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
32870af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3297609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3305609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3319784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
33313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3339cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
33453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3346349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3347349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3355d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3357d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3358d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3359d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3360d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3361d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3362d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
336396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
336496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
336596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3366d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3367d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3368d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3371d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3401d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3402609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
34052d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3408609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3419609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
34202d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
34225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3423a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
34245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34252d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3426a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34297fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
34307fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
34317fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
34327fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
34337fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
34347fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
34357fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
34367fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
34373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
34382d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
34435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
34445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
34455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
34555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3456dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3457dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3458dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3459dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
34665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
34785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
34795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
34805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3483d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3484d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3491078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
34923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3493078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
34945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
34955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
34965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3497078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
35023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3503078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3505078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3506349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3514054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3515054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3516054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3517054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3518054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3519054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3520054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3521054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3522054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3523054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3524054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3525054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3526054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3527054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
35405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
35415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
35425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
35435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
35445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
35475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3549dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
35503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3551dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3552dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3553dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
35543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3555dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3556dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3559349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3560349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3573dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3577625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3578625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3579625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3580625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3613f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3617784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
3618609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3620349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3625d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3631d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3633d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3643054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
36545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
3655609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
36565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3657349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
36585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
36595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
36605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
36635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
366531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3666577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3667577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3668577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
36694bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3670577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
36715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3673308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3674308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3675308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3676308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3677308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3678308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3679308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3680308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3681308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3682496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
368321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3684496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3685496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3686496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
368821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36908b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
36918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
36928b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3696d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
3697609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
36982d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3701609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3713d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
3714dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3737609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3743577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3744577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3745577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3746577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3747577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3748577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3749577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
37526aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
375379ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
37546fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3757fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
3758fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
3759fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
3760fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
3761fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
3762fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
3763fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
3764fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
376547aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
3766fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
3767fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
3768fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
3769fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
3770fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
3772fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
3773fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
3774fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
3775fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
3776fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
37775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
37791e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3780cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3781cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
37825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3783cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3784cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
37866fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
37876fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
37886fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
37896fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3819c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
3820609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
3821c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3822349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3823c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3824c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3826c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3827c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3845f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3851ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3852ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3853ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3854ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3855ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3856ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3857ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3858ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3859ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3860ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3861ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3862308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3863ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3864c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3865c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
38795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
38805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
38815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
38825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
38835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3887c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3888c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3889c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
389054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
389154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
3892c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3894d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3898c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3904d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3908c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3920c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3921c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3922c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3923c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
39245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3926c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
39275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
39285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3929c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3936ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3937ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3938ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3939ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3940ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3941ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3942ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3943ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3944ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3945e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
39465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3950d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
39517791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
39525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3953e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3954e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3955e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3956afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3957e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3958e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3959e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3960afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
39635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
39665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
39695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
39705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3973e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
39745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39751065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
39761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
39771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
39781065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
39791065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
39801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3981e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3982e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3984078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3985078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3986078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
39871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3988078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
39911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
39921065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
39931065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
39941065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
39951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
39961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3997c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
39985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
39997791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
40007791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
40015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
40027791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
40035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4004c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4005cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4007c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4009ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4013ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4014ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4015ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4016ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
40170167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4018ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4019ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4020afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
40255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4026d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
40275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
40285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
40295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4030c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4031c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4032c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4033c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
40345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4036c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4038c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4040c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4041c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4042c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4043c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4044c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4045f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4046f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4047f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4048f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4049f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4050054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4051054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4052a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4053e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4054e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
4055054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4056c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4057c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4058c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4059c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4060c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4061c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4062c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4063c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
406454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4065c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4066c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4070c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4071c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4072c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4073c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
407454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
407554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4076d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
407754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
407854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
407954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4080c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4081c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4082c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4083c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4084c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4085c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4086c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4087c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4088c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4090c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4091c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4092c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
40937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
40947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
40957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
40967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
40977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
40987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
40997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4100c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4101c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4102c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4103c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4104c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4105c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4106c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4107c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4108c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4109c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4110c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4112c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
411354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4114c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4115c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4117c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4118c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4119c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4120c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4121c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4122c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4123d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4124c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4125c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4126c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4131c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4132c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4134c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4135c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4136c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4137c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
41385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
41395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
41405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
41425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
41445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4149c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4150c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4151c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
4153c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4157386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
41591173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
41601173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
41611173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
41621173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
41631ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
41641ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
41651ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
41661ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
41715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4172d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
41755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
41765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4177c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4178c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
41795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4182ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
41837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
41847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
41857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4186d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
41877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
41887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
41897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
41907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
41917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
41927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4193a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4194a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4195a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4196a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4197a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4198a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4199a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4200a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4201a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4202a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4203a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4204a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4205a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4206a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4207a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4208a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4209a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
42102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
421194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
421294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
421394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
421494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
421594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
421694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
421794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
421894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
421994ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
422072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
422172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
42222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
42232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
42242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
42252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
42262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
42272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
42282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
42292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
42302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
42312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
42322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
42332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
42342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
42352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
42362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
42372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
42382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
42392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
42402c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
42412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
42422c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
424372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
424472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
424572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
424672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
424772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
424872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
424972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
425072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
425172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
425272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
425372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
425472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
425594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
425694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
425794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
425894ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
425994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
42607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
42617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
42627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
42637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
42647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
42657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
42667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
42677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
42687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
42697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
42707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
42717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
42727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
42737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
42755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
42765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
42785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4286f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
42913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4293cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4294cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
429529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4296cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4297cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4298cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
42995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
430091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
430191bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4302cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
431772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
43256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
43266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
43276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
43286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
43296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
43306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
43316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
43326463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
43336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
43346463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
43356463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
43366463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
43376463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
43386463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
43396463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4340d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
43416463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
43426463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
43436463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
43446463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
43793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
438472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4392d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4393d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4394d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4395d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4396d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4397d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4398d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4399d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4400d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4401d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4402d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4403d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4404d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4405d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4406d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
44076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
44086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
44096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
44106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
44116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
44126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4439f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4440349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4441349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4444f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4445ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4449054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4450054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4451054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4452054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4453054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4454054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4455054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4456054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4457054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4458054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4459054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
44604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
44614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
44624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4464054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4481349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4482349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4490054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4491c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4492054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4493054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4494054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4495054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4496054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4498349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
44993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4500349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4501349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4502349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4503349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4504349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4512349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4513349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
45173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4530c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4531c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4532c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
453354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4534c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4535c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4536349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4537349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
45507a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4551d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4552d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4553d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4554d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4555d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4556d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4557d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4558349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4559349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4577496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4578496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4579496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4580496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4581496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4582496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4583496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4584496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4585496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4586496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4587496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4588a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4589a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4590a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4591a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4592a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4593a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4594a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4595a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4596a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4597a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4598a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4599a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4600a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4601a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4602a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4603a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4604a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
46057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
46067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
46076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
46087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
46097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
46107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
46117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
46124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
46134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
46144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
46154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
46164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
46174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
46184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
46194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
46204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
46214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
46224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
46234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
46244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4633a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4634a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4635530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4636a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4637a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4638a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4639a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4640a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4641a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4642a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4643a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4644a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4645a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4646a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4647a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4648a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4649a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4650a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4651a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4652a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4653a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4654a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
465572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
465672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
465772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
465872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
465972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
466072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
466172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
466272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
466372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
466472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
466572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
466672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
466772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
466872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
466972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
467072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4671e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4672e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4673e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4674e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4675b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4676b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4677e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4678e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4679e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4680e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4681b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4682b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4683b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4684b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4685b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4686b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4687b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4688b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4689b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4690b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4691b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4692b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4693b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4694b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4695b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4696b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4697e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4698e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4699a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4700a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4701a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
47026507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
47036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
4704d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
47056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
47066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
47076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
47086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
47096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
47106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
47116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
47126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
472031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4721054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4727349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
473031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
473131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
47333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4752f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4757f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4775349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4777349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
47783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4779349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4780349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
47953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4817cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4818cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4819cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
482029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4821cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4822cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4823cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
48245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4825d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4826755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4827755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4828755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4829755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4830755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4831755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4832755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4833755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4834cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
484031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
484131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
48423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4845349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4846349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4847349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4848349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4864f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
48655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
48665778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4897f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
48983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
489931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
49005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
490131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
49135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4919349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4920349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4921349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4922349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4923349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4924349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4925349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
49300af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
49325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49400167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
49410167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4942bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4943bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4944bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4945bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4946bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4947bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4948bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4960f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4969f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4973f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
50023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5013c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5025f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
50303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5060f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
50627a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5063d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5064d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5073e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5074e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5075e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5076e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5077e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5089349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5090349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5091349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5092349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5093609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5094349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5095349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5096349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5097349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
50983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5099349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5100349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5101349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5102349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5103349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5104349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5105349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5113f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5119f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5125f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
51297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
51307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
51317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
51327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5134d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5140dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5141dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5142f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5143f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5144f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5145f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5151