ACodec.cpp revision 8045853d03649f43ea2f7107e7d2dbb9b2d20855
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
37afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
391173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
52f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
75609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
88609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
94609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
162784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
187ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
188ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
363609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
36854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
371e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
3729806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
374054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
375054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
376a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
37794ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
3782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
3792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
380609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
38172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mCreateInputBuffersSuspended(false) {
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
383c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
396dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
414a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
415a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
416a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
417a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
418a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
419a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4265778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4405778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
444f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4457a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
449f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
456c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
460496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
461496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
462496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
485054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
486054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
487054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
497609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
509ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
510ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
512afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
513afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
514afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
515afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
517308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
518308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
521ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
522ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
523ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
525ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
526308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
527308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
528308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
529308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
536ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
537ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
538ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
551d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
555eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
556eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
558eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
560eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
569054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
570054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
571054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
59029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
595e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
596e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
597e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
598e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
599e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
600e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
601e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
602e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
603e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
604e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
605e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
606e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
607e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
608e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
609e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
610e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
611e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
612e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
613e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
614e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
615e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6173c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6183c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6193c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6205ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6213c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6223c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6243c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
636bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
637bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
638bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
639bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
640bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
641bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
642bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
643bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6503c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
65329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
658258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
659258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
661258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
662258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
66329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
664258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
665258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
666258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
667258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
668e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
669e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
6701faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
6711faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
672e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
673e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
674e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
675e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
676e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
677e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
678e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
6791faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
6801faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
681e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
682e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
683258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
684258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
685258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
686258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
687e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
688e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
689e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
690e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
691e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
692609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
693e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
694e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
695e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
696258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
697258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
698258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
699258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
70429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
709054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
710054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
712054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
713054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
714054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
715054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
717054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
718054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
719054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
720e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
721054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
722609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7288ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7291e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
73129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
73674006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
73774006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
73974006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
74074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
74174006804065941841883c4b46ee785070164023fJamie Gennis
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
746609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
74774006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75174006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
75274006804065941841883c4b46ee785070164023fJamie Gennis
753609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
76574006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
786e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
788609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
807054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
812609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
813054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
816054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
818054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
819054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
821054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
829609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
843609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8471e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
856f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8578ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8581e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8601e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
86129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
862c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
863c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
896d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
897d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
898d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
900d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
901d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
902d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
903d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
904d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
905d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
907054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
908d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
909d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
910054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
911054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
929349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9342ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
9352ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
9362ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
9372ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
965f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9952944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9962944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9972944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9982944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1005729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1006729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1007bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1008bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1009c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1010c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1011c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1012c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
10152472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
10162472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
102194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
102294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
102394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
102494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1025ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1026ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
10272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
10282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1029ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1030ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1031774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1032774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
103397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
103497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10695ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1086e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1087e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1088e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1111308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1112308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1114308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1115308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1116308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1118308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11233a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11243a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11253a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
11263a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
11273a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11283a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11293a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
11303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
11313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
11323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
11343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
11353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1145308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1146308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1147308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1148308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1149308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1150308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1151308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1152308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1153308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1154308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1155308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1156308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1157308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1158308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1159308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1160308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1161308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1162308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1163a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1164a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1165a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1166a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1167a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1168a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
116994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
117094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
11712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
11722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
11732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
11742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
11752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
117694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
117772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
117872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
117972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
118072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
118172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
118272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1183308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1184308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1186054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1187054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1188054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1189054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1191e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1193054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1194054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1195054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1196054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1197054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1198fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1199fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1200fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1201fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1202fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1203fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1204fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1205fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1206fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1207fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1208fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1209fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1210fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1211fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1212fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1213fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1214fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1215fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1216fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1217fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1218fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1219fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1220fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1221fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1222fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1223fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1224fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1225fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1226fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1227fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1228fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
122984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1230fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1231fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1232fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1233fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1234fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1235fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1236fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1238e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                if (err == OK) {
1239e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-width", maxWidth);
1240e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-height", maxHeight);
1241e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("adaptive-playback", true);
1242e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
1243fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1244fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1245054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1246054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1247054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1248054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1249e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            inputFormat->setInt32("adaptive-playback", true);
1250054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
12510167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
12520167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
12530167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
12540167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
12550167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12560167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1257e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1258e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1259e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1260e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1261e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1262e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1263e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1264054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1265054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1266308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
127089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
127242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
127342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
127442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
127542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
127642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
127742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
127842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
127942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
128042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
128142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
128242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
128342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
128442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1291aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1292b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
12938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
12948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1295ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1296ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1298aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1299aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1300aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1301b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1302b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1303b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1304ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
13068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
13078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13088045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
13098045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
13118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13128045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
13138045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13148045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
13158045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13168045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
13178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13188045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
13198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13208045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
13218045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
13238045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
13258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
13268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
13278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
13288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1329ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
13304471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
13318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                    isADTS != 0, sbrMode, maxOutputChannelCount, drc);
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1333729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1335729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1337729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1338729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1339729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1340729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1341729de186450f78c099637e1fce743fe531862c52Andreas Huber
1342729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
13492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
13502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
13512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
13522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
13532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
13542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
13552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
13562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1357516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1358516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
13592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
13602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1361516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1362516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1363516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
13652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1366516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1367516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1368516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
13702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
13712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1372516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1373516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
13742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1375ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1376ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1377ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1378ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1379ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1380ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1381ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1382ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1383ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
138497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
138597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
138697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
138797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
138897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
138997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
139097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
139197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
139297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1394729de186450f78c099637e1fce743fe531862c52Andreas Huber
13954471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13964471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13974471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13984471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13998b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
14008b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
14018b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
14029806555d3930be43e11106281dee354820ac1c88Andreas Huber
14038b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
14048b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
14058b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
14068b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
14079806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
14089806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
14099806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
14109806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
14119806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
14129806555d3930be43e11106281dee354820ac1c88Andreas Huber
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1420e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1421e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1422e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1423e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1424e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1492aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
14938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
14948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t maxOutputChannelCount, const drcParams_t& drc) {
1495ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1496ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1497ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1498ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1559aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1561b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1562b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1563b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1564b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1565b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1566b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1567b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1568b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1569b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1570b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1571b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1572b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1573b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1574b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1575b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1576b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1577b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1578b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1579b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1580b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1581b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1582b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1583b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1584b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1585b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1586b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1611ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1612ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1613ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1614ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1615ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
16188045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
16198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
16208045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
16218045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
16228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
16238045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
16248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
16258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
16278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
16288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
16298045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
16308045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
16318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
16328045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
16338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
163697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
163797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
163897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
163997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
164097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
164197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
164297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
164397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
164497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
164597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
164697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
164797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
164897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
164997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
165097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
165197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
165297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
165397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
165497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
165597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
165697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
165797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
165897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
165997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
166097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
166197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
166297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
166397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
166497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
166597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
166697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
166797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
166897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
166997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
167097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
167197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
167297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
167397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1720729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1721729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1723729de186450f78c099637e1fce743fe531862c52Andreas Huber
1724729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1725729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1726729de186450f78c099637e1fce743fe531862c52Andreas Huber
1727729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1728729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1729729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1730729de186450f78c099637e1fce743fe531862c52Andreas Huber
1731729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1736729de186450f78c099637e1fce743fe531862c52Andreas Huber
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1740729de186450f78c099637e1fce743fe531862c52Andreas Huber
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1745729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1746729de186450f78c099637e1fce743fe531862c52Andreas Huber
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1750729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1751729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1752729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1753729de186450f78c099637e1fce743fe531862c52Andreas Huber
17542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
17552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
17562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
17572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
17582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
17592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
17602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
17612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
17622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
17632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
17642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
17652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
17662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
17672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
17682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
17692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
17702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
17712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
17722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
17732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
17742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
17752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
17762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
17772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
17782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
17792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
17802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
17812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1782729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1783729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1784729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1785729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1786729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1787729de186450f78c099637e1fce743fe531862c52Andreas Huber
1788729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1789729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1790729de186450f78c099637e1fce743fe531862c52Andreas Huber
1791729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1792729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1793729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1794729de186450f78c099637e1fce743fe531862c52Andreas Huber
1795729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1796729de186450f78c099637e1fce743fe531862c52Andreas Huber
1797729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1798729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1799729de186450f78c099637e1fce743fe531862c52Andreas Huber
1800729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1801729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1802729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1803729de186450f78c099637e1fce743fe531862c52Andreas Huber
1804729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1805729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1806729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1807729de186450f78c099637e1fce743fe531862c52Andreas Huber
1808729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1809729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1810729de186450f78c099637e1fce743fe531862c52Andreas Huber
1811729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1812729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1813729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1814729de186450f78c099637e1fce743fe531862c52Andreas Huber
1815729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1816729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1817729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1818729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1819729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1820729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1821729de186450f78c099637e1fce743fe531862c52Andreas Huber
1822c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1823c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1824729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1825729de186450f78c099637e1fce743fe531862c52Andreas Huber
1826729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1827729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1828729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1829729de186450f78c099637e1fce743fe531862c52Andreas Huber
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1889f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1906e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1907e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1908e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1909e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1910e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
19112472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
1912e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1913e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1914e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
191594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
191694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1917e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1918e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1921e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1922e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1923e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1924e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1925e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1926e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1927e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1930e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1931e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1932e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1933e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1934e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1935e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1936e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1937e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1938e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1939e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1940e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1941e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1942e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1943e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1944e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1945e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1946e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1947e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1948e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
195289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
195389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
195489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
195589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
195689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
195789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
195889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
197489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
197589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
197689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
197789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
197889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
197989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
198089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
198189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
198289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
198389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
198489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
198589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
198689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2152c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2153c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2154c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2155c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
215689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
215789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
215889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
215989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
216089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
21710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
21720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
21730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
21740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
21760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
21780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
21790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
21800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
21810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
21840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
21870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
21880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
21890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
21900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
21930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
21950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
21960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
21990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
22020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
22030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
22040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
22050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
22060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
221996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
222096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
222196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
222296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
222396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
222496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
222596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
222696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
223496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
223596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
229996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
231696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
237596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
239196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
239296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
24030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
24040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
24050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
24060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
24070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
24080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
24090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
24100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
24110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
24120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
24457c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
24467c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
24477c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
248996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2492c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2493c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2494c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2495c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2496c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2497c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2498c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2499c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2500c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2501c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2502c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2503c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2504c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2505c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2506c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2507c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2508c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2509c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2510c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2511c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2512c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2513c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2514c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2515c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2516c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2517c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2518c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2519c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2520c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2521c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2522c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2523c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2524c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2525c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2526c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2527c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2528c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2529c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2530c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2531c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2532c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2533c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2534c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2535c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2536c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2537c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2538c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2539c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2540c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2541c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2542c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2543c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2544c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2545c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2546c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2547c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
254889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
254989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
25504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
25514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
25524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
25534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
25544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
25554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
25564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
25574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
25584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
25594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
25604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
256189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
256289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
256389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
25644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
256589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
256689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
256789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
25684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
25694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
25704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
25714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
25724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
25734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
25754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
25784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
25794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
25804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
25824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
25834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
25854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
25864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
25884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
25894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
25904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
25944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
25954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
25964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
25974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
25984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
25994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
26004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
26014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
26024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
26034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
26054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
26064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
26074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
26084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
26094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
26104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
26114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
26134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
26144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
26154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
26174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
26184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
26194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
26204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
26214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
26224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
26234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
26244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
262589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
262689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
262789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
265496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
265596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
266896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2700f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2747d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2748d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2749d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2750d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2751d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2752d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2753d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2754d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2755d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2756d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2757d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2758d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2759d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2760d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
27617e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
27627e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
27637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
27657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
27667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
27687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
27697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
27707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
27717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
27737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
27747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
27757e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
27767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
27777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
27787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
27797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2780e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
27817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2782c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2783c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2784c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2785c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
27867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
27877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
27887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2796609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
282703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnarvoid ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
282803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
282903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
283003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
283103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
283203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
283303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
283403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
283503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // we need stride and slice-height to be non-zero
283603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
283703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
283803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
283903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        return;
284003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
284103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
284203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
284303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
284403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
284503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
284603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
284703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
284803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
284903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
285003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
285103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        return;
285203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
285303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
285403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
285503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
285603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
285703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
285803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
285903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
286003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
286103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
286203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
286303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
286403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
286503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
286603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
286703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
286803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
286903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
287003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
287103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
287203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
287303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
287403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
287503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
287603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
287703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
287803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
287903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
288003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
288103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
288203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
288303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
288403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
288503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
288603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
288703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
288803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
288903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
289003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
289103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
289203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
289303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
289403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
289503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
289603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
289703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
289803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
289903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
290003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
290103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
290203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
2903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
2904e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
290531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
290631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
2907e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
290831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
290931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
291031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
291131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
291231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2913e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
2914e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
291531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
291631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
291731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
291831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
291931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2920e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
2921e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
2922e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2923e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
2924e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2925e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2926e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
2927e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
2928e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
2929e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
293003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
293103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
293203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
293303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
293403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
293503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
293603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
293703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
293803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
293903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    OMX_INDEXTYPE describeColorFormatIndex;
294003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    if (mOMX->getExtensionIndex(
294103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            mNode, "OMX.google.android.index.describeColorFormat",
294203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            &describeColorFormatIndex) ||
294303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        mOMX->getParameter(
294403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            mNode, describeColorFormatIndex,
294503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            &describeParams, sizeof(describeParams))) {
294603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        describeDefaultColorFormat(describeParams);
294703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
294803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
294903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    if (describeParams.sMediaImage.mType != MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN) {
295003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
295103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
295203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
295303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
295403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
295503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
295603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
2957e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
2958e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
2959e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    rect.nPortIndex = kPortIndexOutput;
2960e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2961e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
2962e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexConfigCommonOutputCrop,
2963e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
2964e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
2965e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
2966e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
2967e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
2968e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
296931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
2971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
2972e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
2973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
2974e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2975e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2976e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2977e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
2978577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2979577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2980577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2981e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
2982e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
2983e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2984e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2985e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
29864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
29874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
29884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
29894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
29904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
29914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
29924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
29934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
29944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
29954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
29964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
29974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
29984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
29994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
30004730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
30014730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
30024730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
30034730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
30044730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
30054730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
30064730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
30074730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
30084730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
30094730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
30104730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
30114730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
30124730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
30134730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
30144730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
30154730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
30164730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
30174730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
30184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
30194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
30204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
30214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
30224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
30234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
30244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
30254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
30264730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
30274730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
30284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
30294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3030e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3031e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3032e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3033e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3035e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3037e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3038e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3040e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3041e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
304231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3043e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3044e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3045e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
304631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
304731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
304831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
304931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
305031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
305131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
305231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
305397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3054e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3057e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3058e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3060e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3061e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3062e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3063e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3064e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
306514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3066e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3067e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
306814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
306914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
307014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
307114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
307214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
307314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3074e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3075e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3076e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3077e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3078e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3079e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3080e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
30818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3082e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
30838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
30849806555d3930be43e11106281dee354820ac1c88Andreas Huber
3085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3086e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3087e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3088e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3089e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3090e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3091e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3092e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3093e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3094e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3095e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3096e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3098e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3099e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3100e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3101e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3102e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3103e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3106e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
31079806555d3930be43e11106281dee354820ac1c88Andreas Huber
3108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3109e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3110e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3113e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3115e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3116e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3117e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3118e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3119e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3120e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3121e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3122e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3123e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3124e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3125e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3126e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3127e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3128e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3129e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3130e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3131e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3132e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3133e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3134e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3135e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3136e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3137e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3138e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3139e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3140e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3141e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3142e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3143e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3144e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3145e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3146e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3147e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3148e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3149e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3150e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3151e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3152e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3153e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3154e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3155e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3156e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3157e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3158e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3159e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3161e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3163e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3164e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3165e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3166e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3167e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3169e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3171e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3172e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3176e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3177e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3178e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
317997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
318097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
318197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
318297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
318497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
318597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
318697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
318797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
318897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
318997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
319097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
319197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
319297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
319397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
319497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
319597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3196e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
31978c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
31988c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
31998c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
32008c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
32018c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
32028c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
32038c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
32048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
32058c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
32068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
32078c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
32088c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
32098c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
32108c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
32118c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
32128c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
32138c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
32148c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
3215e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3216e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3217e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3218e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
321931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
322031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
322131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
322231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
322331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
322431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
322531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3226e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3227e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3228e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3229e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
3230e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
3231e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3232e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3233e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3234e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3235e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3236e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3238e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3239e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3240e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3241e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3242e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3243e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3244e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3245e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3246e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3247e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3248e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3249e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3250e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3251e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3252e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3253e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3254e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3255e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3256e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3257e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3258e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3259e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3260e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3261e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3262e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
326331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
326431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
326531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
326631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
326731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
32685778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3269cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3270d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3271cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
32725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3273cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3274cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3275cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3276bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3277bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3278bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3279bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3280bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3281bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3282bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3283bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3284bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3285bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3286bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3287bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3288bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3289bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3290bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3291bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3292bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3293bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3294bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3295bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3296bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3297bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3298bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3299bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3300bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3301bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3302bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3303bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3304bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3305bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3306bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3307bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3308bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
330987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
331087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
331187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
331287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
331387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
331487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3315bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3316bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3317bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3318bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3319bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3320bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3321bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3322bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3323bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3324bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3325bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3326bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3327bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3328bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3329bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3330bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3331bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3332bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3333bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3334bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3335bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3336bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3337bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3338bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3339bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3340bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3341bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3342bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3343bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3344bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3345bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
33461e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
33471e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3348bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3349bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3350bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3351bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3352bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3353bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3354bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3355bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3356bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3357bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3358bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3359bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3360bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3361bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3362bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3363bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3364bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3365bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3366bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3367bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3368bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3369bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3370bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3371bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3372bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3373bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3374bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
33751e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3376bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3377bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3378bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3379bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3380bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3381bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3382bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3383bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3384bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3385bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3386bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3387bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3388bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3389bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
33901e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3391bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3392bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3393bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3394bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3395bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3396bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3397bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3398bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3399bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3400bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3401bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3402bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3403bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3404bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3405bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3406bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3407bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3408bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3409bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3410bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3411bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3412bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3413bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3414bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3415bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3416bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3417bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3418bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3419bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3420bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3423eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3424eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3425eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3426496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3427496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3428496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3429496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3430496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3431496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3432496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3433496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3434496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3435496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3436496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3437496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3438496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3439496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3440496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3441496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3442496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3443496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3444eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3445eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3446eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3447eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3448eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3449eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3450eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3451eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3452eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3453eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3454eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3455eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3456eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3457eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3458eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3459eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3460eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3461eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3462eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3463eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3464f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3469ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3470ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
34947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
34957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
34967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
34977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
34987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
34997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
35007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3501ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3502ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3503ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3504ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3505ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3506ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3507ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35195e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
35205e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
35215e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
35225e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
35235e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
35245e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
35255e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
35265e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3528609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
35400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
35410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
35420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
35430af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
35440af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
35450af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
35460af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
35470af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
35480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
35490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3559609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3567609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3581784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
35933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3601cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
36073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3608349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3609349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3621d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
362596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
362696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
362796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3631d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3633d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3663d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3664609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
36672d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3670609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3681609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
36822d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3685a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36872d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3688a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36917fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
36927fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
36937fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
36947fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
36957fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
36967fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
36977fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
36987fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
36993831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
37002d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3718dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3719dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3720dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3721dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
37405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
37415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
37425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3753078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
37543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3755078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
37565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3759078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3760d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3762d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3763d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
37643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3765078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3766d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3767078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3768349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3769d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3770d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3771d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3772d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3773d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3774d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3775d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
38025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
38065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3811dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
38123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3813dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3814dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3815dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
38163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3817dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3818dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3821349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3822349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3835dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3839625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3840625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3841625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3842625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3879784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
3880609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
38815778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3882349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3884d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3885d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3886d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3887d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3888d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3889d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3890d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3891d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3892d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3893d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3894d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3895d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3896d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3897d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3898d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3899d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
39165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
3917609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
39185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3919349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
39205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
39215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
39225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
39265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
392731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3928577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3929577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3930577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
39314bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3932577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
39335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3935308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3936308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3937308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3938308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3939308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3940308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3941308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3942308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3943308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3944496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
394521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3946496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3947496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3948496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
39495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
395021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39528b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
39538b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
39548b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
39555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3958d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
3959609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
39602d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3963609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3975d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
3976dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3999609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4005577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4006577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4007577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4008577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4009577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4010577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4011577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
40146aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
401579ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
40166fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4019fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4020fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4021fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4022fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4023fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4024fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4025fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4026fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
402747aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4028fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4029fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4030fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4031fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4032fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
40335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4034fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4035fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4036fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4037fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4038fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
40395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
40411e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4042cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4043cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
4045cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4046cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
40486fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
40496fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
40506fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
40516fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4081c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4082609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4083c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4084349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4085c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4086c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4088c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4089c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4107f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4112c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4113ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4114ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4115ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4116ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4117ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4118ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4119ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4120ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4121ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4122ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4123ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4124308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4125ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4126c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
41415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
41425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
41435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
41445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4149c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4150c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
415254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
415354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4154c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4156d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4160c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4166d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4170c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4183c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
41865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
41895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
41925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4200ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4202ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4203ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4204ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4205ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4206ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4207e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
42137791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
42145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4215e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4216e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4217e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4218afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4219e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4220e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4221e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4222afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
42235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
42245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
42255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
42275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
42285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
42315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
42325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
42335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
42345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4235e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
42365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
42381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
42391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
42401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
42411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
42421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4243e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4244e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4246078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4247078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4248078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
42491065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4250078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42521065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
42531065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
42547a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
42557a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
42561065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
42571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
42581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
42591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
42601065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4261c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
42625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
42637791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
42647791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
42655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
42667791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
42675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4268c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4269cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4271c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4273ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4277ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4278ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4279ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4280ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
42810167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4282ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4283ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4284afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
42895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4290d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
42915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
42925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
42935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
42985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4300c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4301c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4302c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4309f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4310f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4311f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4312f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4313f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4314054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4315054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4316a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4317e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4318e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
4319054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4321c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4322c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
432854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4329c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4331c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4332c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4334c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4336c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4337c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
433854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
433954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4340d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
434154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
434254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
434354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4345c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4346c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4347c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4350c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4352c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4355c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4356c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
43577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
43587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
43597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
43607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
43617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
43627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
43637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4366c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4367c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4368c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4369c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4370c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4371c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4372c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4373c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4376c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
437754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4378c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4379c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4380c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4381c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4382c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4383c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4384c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4385c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4386c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4387d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4388c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4389c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4390c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4391c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4392c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4393c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4394c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4395c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4396c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4397c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
44025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
44035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
44045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
44065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
44085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
44095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
44115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4413c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4414c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4415c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
44165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
4417c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
44185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4421386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
44225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
44231173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
44241173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
44251173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
44261173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
44271ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
44281ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
44291ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
44301ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
44355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4436d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4437e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4438e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
44395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
44405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4441c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
44435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4446ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
44477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
44487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
44497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4450d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
44517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
44527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
44537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
44547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
44557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
44567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4457a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4458a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4459a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4460a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4461a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4462a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4463a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4464a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4465a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4466a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4467a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4468a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4469a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4470a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4471a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4472a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4473a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
44742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
447594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
447694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
447794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
447894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
447994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
448094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
448194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
448294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
448394ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
448472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
448572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
44862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
44872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
44882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
44892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
44902c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
44912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
44922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
44932c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
44942c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
44952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
44962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
44972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
44982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
44992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
45002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
45012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
45022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
45032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
45042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
45052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
45062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
450772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
450872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
450972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
451072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
451172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
451272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
451372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
451472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
451572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
451672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
451772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
451872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
451994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
452094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
452194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
452294ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
452394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
45247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
45257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
45267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
45277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
45287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
45297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
45307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
45317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
45327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
45337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
45347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
45357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
45367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
45377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4538c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
45395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
45405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
45425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
45553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4557cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4558cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
455929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4560cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4561cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4562cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
45635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
456491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
456591bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4566cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
458172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
45896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
45906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
45916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
45926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
45936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
45946463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
45956463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
45966463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
45976463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
45986463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
45996463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
46006463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
46016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
46026463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
46036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4604d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
46056463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
46066463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
46076463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
46086463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4638f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
46433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
464872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4655d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4656d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4657d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4658d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4659d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4660d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4661d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4662d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4663d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4664d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4665d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4666d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4667d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4668d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4669d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4670d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
46716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
46726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
46736507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
46746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
46756507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
46766507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4703f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4704349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4705349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4708f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4709ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4713054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4714054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4715054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4717054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4718054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4719054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4720054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4721054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
47244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
47254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
47264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4745349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4746349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4755c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4762349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
47633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4764349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4765349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4766349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4767349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4768349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47713cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
47733cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
47743cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
47753cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
47763cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
47773cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
47783cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
4779349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4780349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
47843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4795c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4796c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4797c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4798c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4799c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
480054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4801c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4802c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4803349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4804349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
48177a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4818d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4819d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4820d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4821d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4822d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4823d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4824d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4825349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4826349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4844496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4845496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4846496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4847496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4848496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4849496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4850496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4851496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4852496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4853496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4854496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4855a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4856a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4857a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4858a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4859a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4860a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4861a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4862a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4863a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4864a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4865a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4866a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4867a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4868a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4869a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4870a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4871a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
48727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
48737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
48746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
48757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
48767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
48777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
48787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
48794dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
48804dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
48814dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
48824dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
48834dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
48844dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
48854dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
48864dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
48874dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
48884dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
48894dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
48904dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
48914dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4900a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4901a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4902530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4903a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4904a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4905a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4906a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4907a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4908a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4909a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4910a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4911a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4912a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4913a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4914a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4915a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4916a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4917a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4918a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4919a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4920a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4921a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
492272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
492372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
492472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
492572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
492672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
492772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
492872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
492972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
493072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
493172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
493272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
493372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
493472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
493572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
493672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
493772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4938e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4939e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4940e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4941e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4942b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4943b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4944e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4945e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4946e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4947e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4948b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4949b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4950b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4951b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4952b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4953b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4954b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4955b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4956b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4957b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4958b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4959b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4960b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4961b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4962b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4963b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4964e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4965e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4966a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4967a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4968a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
49696507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
49706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
4971d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
49726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
49736507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
49746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
49756507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
49766507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
49776507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
49786507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
49796507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
498731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4988054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4994349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
499731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
499831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
50003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5019f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5024f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5042349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5044349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
50453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5046349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5047349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
50623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5084cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5085cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5086cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
508729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5088cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5089cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5090cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
50915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
5092d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5093755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5094755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5095755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5096755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5097755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5098755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5099755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5100755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5101cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
510731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
510831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
51093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5112349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5113349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5114349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5115349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5131f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
51325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
51335778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5136f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5164f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
51653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
516631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
51675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
516831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5171f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
51805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5186349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5187349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5188349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5189349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5190349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5191349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5192349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
51970af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
51995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52070167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
52080167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5209bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5210bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5211bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5212bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5213bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5214bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5215bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5220f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5227f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5236f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
52693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5272f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5292f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
52973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
53297a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5330d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5331d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5340e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5341e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5342e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5343e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5344e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5356349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5357349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5358349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5359349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5360609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5361349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5362349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5363349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5364349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
53653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5366349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5367349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5368349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5369349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5370349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5371349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5372349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
53967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
53977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
53987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
53997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5401d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5407dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5408dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5409f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5410f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5411f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5412f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5418