ACodec.cpp revision e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4
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 {
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
127842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
127942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
128042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
128142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
128242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
128342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
128442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
128542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
128642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
128742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
128842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
128942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
129042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1297aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1300ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1301aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1302aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1303aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1304ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1305ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
13064471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
13074471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1309729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1311729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1313729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1314729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1315729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1316729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1317729de186450f78c099637e1fce743fe531862c52Andreas Huber
1318729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
13252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
13262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
13272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
13282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
13292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
13302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
13312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
13322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1333516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1334516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
13352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
13362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1337516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1338516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1339516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
13412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1342516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1343516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1344516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
13462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
13472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1348516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1349516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
13502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1351ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1352ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1353ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1354ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1355ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1356ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1357ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1358ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1359ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
136097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
136197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
136297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
136397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
136497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
136597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
136697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
136797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
136897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1370729de186450f78c099637e1fce743fe531862c52Andreas Huber
13714471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13724471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13734471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13744471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13758b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
13768b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
13778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13789806555d3930be43e11106281dee354820ac1c88Andreas Huber
13798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13808b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13839806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13849806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13859806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13869806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13879806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13889806555d3930be43e11106281dee354820ac1c88Andreas Huber
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1396e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1397e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1398e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1399e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1400e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1468aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1469aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1470ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1471ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1472ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1473ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1534aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1560ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1561ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1562ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1563ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1564ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
157097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
157197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
157297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
157397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
157497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
157597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
157697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
157797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
157897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
157997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
158097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
158197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
158297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
158397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
158497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
158597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
158697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
158797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
158897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
158997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
159097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
159197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
159297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
159397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
159497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
159597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
159697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
159797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
159897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
159997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
160097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
160197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
160297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
160397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
160497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
160597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
160697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
160797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1657729de186450f78c099637e1fce743fe531862c52Andreas Huber
1658729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1659729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1660729de186450f78c099637e1fce743fe531862c52Andreas Huber
1661729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1662729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1663729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1664729de186450f78c099637e1fce743fe531862c52Andreas Huber
1665729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1670729de186450f78c099637e1fce743fe531862c52Andreas Huber
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1674729de186450f78c099637e1fce743fe531862c52Andreas Huber
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1679729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1680729de186450f78c099637e1fce743fe531862c52Andreas Huber
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1684729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1685729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1686729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1687729de186450f78c099637e1fce743fe531862c52Andreas Huber
16882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
17002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
17012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
17022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
17032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
17042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
17052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
17062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
17072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
17082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
17092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
17102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
17112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
17122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
17132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
17142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
17152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1716729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1717729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1718729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1719729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1720729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1721729de186450f78c099637e1fce743fe531862c52Andreas Huber
1722729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1723729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1724729de186450f78c099637e1fce743fe531862c52Andreas Huber
1725729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1726729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1727729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1728729de186450f78c099637e1fce743fe531862c52Andreas Huber
1729729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1730729de186450f78c099637e1fce743fe531862c52Andreas Huber
1731729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1732729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1733729de186450f78c099637e1fce743fe531862c52Andreas Huber
1734729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1735729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1736729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1737729de186450f78c099637e1fce743fe531862c52Andreas Huber
1738729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1739729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1740729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1741729de186450f78c099637e1fce743fe531862c52Andreas Huber
1742729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1743729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1744729de186450f78c099637e1fce743fe531862c52Andreas Huber
1745729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1746729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1747729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1748729de186450f78c099637e1fce743fe531862c52Andreas Huber
1749729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1750729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1751729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1752729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1753729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1754729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1755729de186450f78c099637e1fce743fe531862c52Andreas Huber
1756c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1757c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1758729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1759729de186450f78c099637e1fce743fe531862c52Andreas Huber
1760729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1761729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1762729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1763729de186450f78c099637e1fce743fe531862c52Andreas Huber
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1823f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
18452472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
1846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1847e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1848e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
184994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
185094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1851e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1855e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1856e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1857e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1860e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1861e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1864e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1865e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1866e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1867e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1868e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1869e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1870e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1871e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1877e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1878e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1879e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1881e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1882e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2067c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2068c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2069c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2070c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
207189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
207289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
207389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
207489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
207589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
20860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
20870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
20880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
20890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
20910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
20930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
20960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
20990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
21020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
21030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
21040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
21050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
21080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
21100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
21110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
21120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
21140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
21170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
21180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
21190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
21200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
21210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
213396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
213496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
213596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
213696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
213796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
213896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
213996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
214096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
214196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
214996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
215096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
223096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
223196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
229096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
230696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
230796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
23180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
23190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
23200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
23210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
23220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
23230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
23240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
23250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
23607c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
23617c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
23627c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
240496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2407c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2408c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2409c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2410c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2411c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2412c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2413c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2414c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2415c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2416c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2417c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2418c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2419c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2420c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2421c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2422c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2423c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2424c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2425c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2426c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2427c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2428c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2429c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2430c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2431c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2432c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2433c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2434c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2435c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2436c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2437c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2438c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2439c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2440c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2441c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2442c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2443c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2444c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2445c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2446c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2447c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2448c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2449c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2450c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2451c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2452c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2453c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2454c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2455c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2456c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2457c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2458c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2459c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2460c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2461c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2462c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
246389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
246489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
24654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
24664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
24674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
24684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
24694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
24704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
24714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
24724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
24734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
24744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
24754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
247689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
247789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
247889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
24794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
248089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
248189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
248289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
24834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
24844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
24854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
24864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
24874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
24884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
24904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
24914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
24924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
24934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
24944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
24954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
24964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
24974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
24984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
24994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
25004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
25014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
25024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
25034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
25044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
25054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
25094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
25104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
25114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
25124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
25134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
25144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
25164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
25174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
25184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
25204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
25214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
25224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
25234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
25244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
25254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
25264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
25284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
25294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
25304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
25324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
25334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
25344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
25354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
25364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
25374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
25384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
25394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
254089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
254189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
254289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
25545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
256996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
257096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
258396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2662d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2663d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2664d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2665d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2666d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2667d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2668d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2669d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2670d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2671d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2672d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2673d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2674d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2675d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
26767e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
26777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
26787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
26807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
26817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
26837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
26847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
26857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
26867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
26887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
26897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
26907e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
26917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
26927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
26937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
26947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2695e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
26967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2697c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2698c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2699c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2700c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
27017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
27027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
27037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2711609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
2712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2721f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
274203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnarvoid ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
274303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
274403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
274503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
274603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
274703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
274803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
274903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
275003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // we need stride and slice-height to be non-zero
275103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
275203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
275303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
275403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        return;
275503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
275603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
275703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
275803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
275903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
276003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
276103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
276203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
276303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
276403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
276503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
276603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        return;
276703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
276803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
276903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
277003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
277103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
277203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
277303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
277403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
277503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
277603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
277703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
277803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
277903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
278003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
278103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
278203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
278303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
278403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
278503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
278603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
278703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
278803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
278903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
279003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
279103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
279203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
279303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
279403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
279503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
279603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
279703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
279803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
279903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
280003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
280103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
280203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
280303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
280403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
280503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
280603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
280703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
280803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
280903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
281003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
281103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
281203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
281303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
281403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
281503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
281603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
281703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
2818e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
2819e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
282031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
282131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
2822e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
282331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
282431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
282531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
282631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
282731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2828e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
2829e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
283031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
283131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
283231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
283331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
283431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2835e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
2836e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
2837e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2838e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
2839e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2840e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
2842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
2843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
2844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
284503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
284603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
284703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
284803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
284903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
285003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
285103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
285203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
285303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
285403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    OMX_INDEXTYPE describeColorFormatIndex;
285503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    if (mOMX->getExtensionIndex(
285603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            mNode, "OMX.google.android.index.describeColorFormat",
285703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            &describeColorFormatIndex) ||
285803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        mOMX->getParameter(
285903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            mNode, describeColorFormatIndex,
286003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                            &describeParams, sizeof(describeParams))) {
286103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        describeDefaultColorFormat(describeParams);
286203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
286303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
286403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    if (describeParams.sMediaImage.mType != MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN) {
286503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
286603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
286703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
286803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
286903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
287003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
287103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
2872e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
2873e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
2874e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    rect.nPortIndex = kPortIndexOutput;
2875e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2876e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
2877e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexConfigCommonOutputCrop,
2878e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
2879e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
2880e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
2881e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
2882e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
2883e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
288431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2885e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
2886e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
2887e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
2888e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
2889e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2891e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2892e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
2893577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2894577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2895577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2896e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
2897e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
2898e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2899e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2900e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
29014730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
29024730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
29034730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
29044730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
29054730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
29064730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
29074730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
29084730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
29094730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
29104730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
29114730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
29124730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
29134730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
29144730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
29154730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
29164730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
29174730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
29184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
29194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
29204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
29214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
29224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
29234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
29244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
29254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
29264730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
29274730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
29284730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
29294730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
29304730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
29314730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
29324730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
29334730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
29344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
29354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
29364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
29374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
29384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
29394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
29404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
29414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
29424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
29434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
29444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
2945e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
2946e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2947e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
2948e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
2949e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
2950e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
2951e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
2952e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
2953e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
2954e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
2955e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2956e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
295731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
2958e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2959e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
2960e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
296131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
296231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
296331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
296431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
296531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
296631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
296731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
296897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2969e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2970e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2971e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2972e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2974e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2975e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2976e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2977e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2978e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2979e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
298014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2981e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2982e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
298314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
298414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
298514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
298614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
298714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
298814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2989e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2990e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2991e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2992e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2993e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2994e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2995e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
29968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2997e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
29988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
29999806555d3930be43e11106281dee354820ac1c88Andreas Huber
3000e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3001e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3002e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3003e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3004e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3005e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3006e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3007e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3008e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3009e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3010e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3011e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3012e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3013e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3014e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3015e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3016e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3017e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3018e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3019e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3020e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3021e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
30229806555d3930be43e11106281dee354820ac1c88Andreas Huber
3023e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3024e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3025e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3026e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3027e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3028e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3029e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3030e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3031e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3032e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3033e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3034e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3035e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3036e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3037e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3038e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3039e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3040e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3041e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3042e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3043e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3044e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3045e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3046e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3047e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3049e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3051e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3052e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3053e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3054e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3057e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3058e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3060e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3061e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3062e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3063e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3064e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3065e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3066e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3067e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3068e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3069e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3070e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3071e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3072e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3073e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3074e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3075e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3076e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3077e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3078e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3079e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3080e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3081e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3082e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3083e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3084e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3085e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3086e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3087e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3088e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3089e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3090e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3091e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3092e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3093e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
309497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
309597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
309697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
309797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3098e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
309997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
310097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
310197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
310297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
310397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
310497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
310597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
310697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
310797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
310897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
310997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
311097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
31128c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
31138c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
31148c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
31158c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
31168c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
31178c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
31188c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
31198c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
31208c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
31218c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
31228c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
31238c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
31248c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
31258c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
31268c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
31278c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
31288c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
31298c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
3130e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3131e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3132e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3133e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
313431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
313531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
313631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
313731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
313831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
313931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
314031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3141e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3142e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3143e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3144e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
3145e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
3146e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3147e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3148e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3149e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3150e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3151e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3152e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3153e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3154e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3155e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3156e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3157e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3158e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3159e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3161e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3163e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3164e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3165e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3166e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3167e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3169e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3171e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3172e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3176e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3177e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
317831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
317931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
318031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
318131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
318231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
31835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3184cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3185d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3186cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3188cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3189cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3190cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3191bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3192bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3193bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3194bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3195bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3196bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3197bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3198bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3199bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3200bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3201bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3202bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3203bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3204bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3205bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3206bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3207bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3208bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3209bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3210bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3211bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3212bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3213bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3214bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3215bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3216bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3217bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3218bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3219bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3220bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3221bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3222bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3223bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
322487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
322587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
322687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
322787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
322887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
322987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3230bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3231bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3232bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3233bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3234bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3235bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3236bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3237bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3238bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3239bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3240bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3241bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3242bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3243bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3244bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3245bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3246bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3247bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3248bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3249bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3250bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3251bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3252bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3253bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3254bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3255bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3256bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3257bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3258bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3259bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3260bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
32611e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
32621e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3263bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3264bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3265bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3266bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3267bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3268bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3269bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3270bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3271bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3272bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3273bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3274bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3275bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3276bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3277bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3278bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3279bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3280bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3281bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3282bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3283bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3284bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3285bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3286bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3287bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3288bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3289bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
32901e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3291bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3292bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3293bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3294bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3295bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3296bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3297bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3298bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3299bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3300bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3301bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3302bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3303bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3304bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
33051e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3306bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3307bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3308bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3309bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3310bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3311bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3312bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3313bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3314bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3315bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3316bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3317bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3318bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3319bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3320bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3321bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3322bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3323bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3324bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3325bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3326bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3327bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3328bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3329bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3330bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3331bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3332bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3333bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3334bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3335bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3338eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3339eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3340eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3341496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3342496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3343496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3344496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3345496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3346496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3347496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3348496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3349496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3350496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3351496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3352496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3353496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3354496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3355496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3356496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3357496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3358496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3359eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3360eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3361eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3362eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3363eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3364eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3365eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3366eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3367eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3368eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3369eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3370eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3371eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3372eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3373eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3374eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3375eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3376eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3377eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3378eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3379f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3384ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3385ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
34097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
34107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
34117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
34127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
34137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
34147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
34157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3416ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3417ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3418ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3419ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3420ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3421ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3422ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34345e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
34355e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
34365e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
34375e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
34385e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
34395e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
34405e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
34415e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3443609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34540af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
34550af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
34560af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
34570af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
34580af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
34590af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
34600af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
34610af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
34620af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
34630af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
34640af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3474609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3482609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3496784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
35083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3516cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
35223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3523349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3524349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3533d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3534d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3535d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3536d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3537d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3538d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3539d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
354096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
354196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
354296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3543d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3578d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
3579609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
35822d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3585609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3596609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
35972d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
35995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3600a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36022d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3603a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36067fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
36077fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
36087fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
36097fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
36107fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
36117fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
36127fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
36137fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
36143831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
36152d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
36325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3633dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3634dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3635dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3636dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
36435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
36555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
36565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
36575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3659d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3661d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3662d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3668078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
36693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3670078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
36715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
36725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
36735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3674078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3676d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3677d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
36793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3680078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3681d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3682078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3683349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3684d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3685d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3686d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3687d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3688d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3689d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3690d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3691054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3692054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3693054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3694054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3695054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3696054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3697054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3698054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3699054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3700054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3701054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3702054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3703054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3704054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3726dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
37273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3728dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3729dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3730dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
37313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3732dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3733dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3736349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3737349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3750dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3754625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3755625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3756625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3757625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3794784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
3795609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
37965778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3797349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3800d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3801d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3802d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3803d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3804d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3805d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3806d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3807d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3808d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3809d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3810d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3811d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3812d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3813d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3814d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
3832609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
38335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3834349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
38405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
38415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
384231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3843577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3844577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3845577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
38464bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3847577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
38485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3850308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3851308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3852308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3853308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3854308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3855308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3856308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3857308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3858308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3859496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
386021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3861496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3862496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3863496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
38645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
386521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
38688b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
38698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
38705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3873d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
3874609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
38752d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
38765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3878609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
38835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
38885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3890d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
3891dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3914609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3920577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3921577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3922577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3923577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3924577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3925577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3926577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
39296aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
393079ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
39316fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3934fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
3935fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
3936fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
3937fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
3938fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
3939fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
3940fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
3941fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
394247aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
3943fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
3944fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
3945fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
3946fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
3947fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
39485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
3949fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
3950fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
3951fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
3952fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
3953fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
39545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
39561e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3957cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3958cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3960cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3961cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
39636fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
39646fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
39656fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
39666fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3996c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
3997609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
3998c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3999349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4000c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4001c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4003c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4004c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4022f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4026c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4028ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4029ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4030ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4031ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4032ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4033ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4034ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4035ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4036ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4037ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4038ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4039308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4040ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4041c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4042c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
40565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
40575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
40585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
40595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
40605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4064c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4065c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4066c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
406754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
406854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4071d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4075c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4081d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4085c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4097c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4098c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4099c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4100c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
41015778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4103c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
41045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
41055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4106c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
41075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4113ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4114ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4115ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4116ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4117ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4118ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4119ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4120ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4121ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4122e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
41235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
41287791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
41295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4130e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4131e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4132e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4133afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4134e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4135e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4136e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4137afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
41385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
41395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
41405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
41425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
41435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
41495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4150e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41521065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
41531065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
41541065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
41551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
41561065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
41571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4158e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4159e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4161078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4162078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4163078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
41641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4165078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
41681065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
41697a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
41707a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
41711065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
41721065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
41731065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
41741065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
41751065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4176c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
41775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
41787791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
41797791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
41805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
41817791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
41825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4183c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4184cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4186c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4188ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4192ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4193ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4194ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4195ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
41960167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4197ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4198ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4199afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4205d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
42065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
42075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
42135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4224f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4225f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4226f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4227f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4228f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4229054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4230054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4231a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4232e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4233e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
4234054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4238c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4239c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
424354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4245c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4248c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
425354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
425454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4255d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
425654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
425754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
425854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
42727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
42737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
42747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
42757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
42767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
42777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4284c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4285c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4286c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4287c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4289c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4290c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4291c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
429254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4300c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4301c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4302d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4316c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
43175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
43185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
43195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
43215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
43235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
43245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
43265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4328c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4329c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4330c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
43315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
4332c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
43335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4336386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
43375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
43381173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
43391173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
43401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
43411173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
43421ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
43431ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
43441ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
43451ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
43505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4351d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4352e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4353e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
43545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
43555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4356c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
43585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
43595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4361ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
43627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
43637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
43647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4365d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
43667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
43677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
43687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
43697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
43707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
43717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4376a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4377a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4378a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4379a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4380a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4381a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4382a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4383a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4384a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4385a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4386a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4387a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4388a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
43892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
439094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
439194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
439294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
439394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
439494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
439594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
439694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
439794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
439894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
439972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
440072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
44012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
44022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
44032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
44042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
44052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
44062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
44072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
44082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
44092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
44102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
44112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
44122c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
44132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
44142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
44152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
44162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
44172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
44182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
44192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
44202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
44212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
442272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
442372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
442472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
442572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
442672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
442772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
442872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
442972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
443072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
443172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
443272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
443372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
443494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
443594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
443694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
443794ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
443894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
44397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
44407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
44417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
44427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
44437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
44447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
44457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
44467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
44477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
44487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
44497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
44507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
44517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
44527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
44545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
44555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
44575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4465f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
44703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4472cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4473cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
447429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4475cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4476cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4477cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
44785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
447991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
448091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4481cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
449672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
45046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
45056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
45066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
45076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
45086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
45096463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
45106463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
45116463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
45126463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
45136463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
45146463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
45156463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
45166463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
45176463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
45186463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4519d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
45206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
45216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
45226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
45236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4553f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
45583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
456372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4570d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4571d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4572d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4573d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4574d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4575d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4576d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4577d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4578d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4579d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4580d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4581d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4582d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4583d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4584d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4585d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
45866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
45876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
45886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
45896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
45906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
45916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4618f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4619349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4620349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4623f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4624ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4628054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4629054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4634054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4635054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4636054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4637054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4638054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
46394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
46404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
46414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4642054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4643054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4644054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4660349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4661349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4670c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4677349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
46783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4679349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4680349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4681349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4682349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4683349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46863cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
46883cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
46893cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
46903cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
46913cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
46923cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
46933cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
4694349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4695349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
46993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4710c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4711c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4712c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4713c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4714c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
471554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4718349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4719349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
47327a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4733d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4734d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4735d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4736d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4737d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4738d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4739d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4740349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4741349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4759496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4760496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4761496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4762496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4763496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4764496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4765496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4766496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4767496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4768496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4769496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4770a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4771a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4772a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4773a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4774a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4775a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4776a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4777a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4778a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4779a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4780a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4781a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4782a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4783a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4784a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4785a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4786a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
47877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
47887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
47896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
47907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
47917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
47927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
47937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
47944dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
47954dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
47964dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
47974dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
47984dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
47994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
48004dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
48014dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
48024dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
48034dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
48044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
48054dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
48064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4816a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4817530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4818a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4819a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4820a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4821a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4822a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4823a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4824a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4825a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4826a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4827a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4828a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4829a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4830a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4831a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4832a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4833a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4834a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4835a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4836a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
483772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
483872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
483972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
484072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
484172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
484272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
484372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
484472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
484572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
484672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
484772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
484872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
484972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
485072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
485172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
485272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4853e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4854e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4855e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4856e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4857b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4858b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4859e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4860e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4861e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4862e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4863b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4864b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4865b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4866b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4867b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4868b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4869b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4870b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4871b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4872b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4873b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4874b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4875b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4876b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4877b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4878b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4879e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4880e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4881a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4882a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4883a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
48846507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
48856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
4886d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
48876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
48886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
48896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
48906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
48916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
48926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
48936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
48946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4895f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
490231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4903054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4909349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
491231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
491331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
49153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4934f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4939f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4957349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4959349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
49603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4961349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4962349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
49773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4999cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5000cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5001cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
500229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5003cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5004cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5005cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
50065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
5007d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5008755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5009755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5010755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5011755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5012755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5013755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5014755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5015755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5016cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
502231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
502331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
50243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5027349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5028349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5029349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5030349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5046f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
50475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
50485778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5051f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
50803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
508131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
50825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
508331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5086f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
50955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5101349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5102349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5103349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5104349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5105349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5106349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5107349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
51120af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5113f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
51145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51220167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
51230167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5124bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5125bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5126bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5127bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5128bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5129bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5130bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5135f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5142f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5151f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5155f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
51843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5207f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
52123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5217f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
52447a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5245d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5246d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5255e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5256e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5257e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5258e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5259e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5271349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5272349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5273349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5274349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5275609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5276349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
52803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5281349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5283349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5284349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5285349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5286349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5287349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
53117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
53127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
53137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
53147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5316d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5322dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5323dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5324f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5325f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5326f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5327f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5333