ACodec.cpp revision 4154795d5526750b7aec5f774831a9e1ba0a3f15
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
3897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
44496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
45f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
187ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
188ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
189ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
199c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
202ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
227c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
271349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
281349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
364afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
366c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
367308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3719806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
374054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
37694ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
3772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
3782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerCaptureUs(-1ll),
3792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
38072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mCreateInputBuffersSuspended(false) {
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
382c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
395dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
407f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
414a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
415a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
416a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
417a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
418a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4195778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4255778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4395778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4447a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
459496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
460496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
461496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
482054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
485054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
486054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
509ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
511afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
512afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
513afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
514afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
516308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
517308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
521ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
522ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
523ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
525308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
526308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
527308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
528308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
536ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
537ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
553eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
555eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
557eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
559eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
562eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
569054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
570054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5985ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5993c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6003c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6013c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6023c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6283c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
635054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
638054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
64129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
644258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
645258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
646e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
647e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
6481faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
6491faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
650e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
651e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
652e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
653e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
654e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
655e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
656e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
6571faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
6581faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
659e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
660e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
661258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
662258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
663258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
664258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
665e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
666e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
667e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
668e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
669e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
670e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        ALOGW("[%s] setting nBufferCountActual to %lu failed: %d",
671e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
672e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
673e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
674258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
675258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
676258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
677258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
68229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
687054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
688054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
689054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
690054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
691054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
692054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
693054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
694054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
695054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
696054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
697054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
698e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
699054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
7003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
702054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
705054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7068ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
70929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
71474006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
71574006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
71774006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
71874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
71974006804065941841883c4b46ee785070164023fJamie Gennis
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
72429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
72574006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72974006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
73074006804065941841883c4b46ee785070164023fJamie Gennis
7313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
74374006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
764e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
807054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
813054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
816054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8251e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
834f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8358ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8361e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8381e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
83929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
840c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
841c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
874d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
875d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
876d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
878d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
879d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
880d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
881d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
882d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
883d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
886d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
887d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
907349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9122ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
9132ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
9142ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
9152ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
943f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9732944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9742944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9752944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9762944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
983729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
984729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
985bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
986bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
987c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
988c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
989c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
990c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
99794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
99894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
99994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
100094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1001ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1002ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
10032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
10042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1005ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1006ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1007774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1008774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
100997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
101097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10455ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1062e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1063e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1064e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1080d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1081d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1082d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1093d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
11023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
11033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
11063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
11073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
11083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
11103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
11113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1121308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1122308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1123308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1124308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1125308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1126308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1127308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1128308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1129308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1130308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1131308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1132308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1133308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1134308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1135308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1136308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1137308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1138308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1139a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1140a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1141a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1142a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1143a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1144a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
114594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
114694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
11472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
11482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
11492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
11502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
11512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
115294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
115372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
115472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
115572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
115672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
115772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
115872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1159308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1160308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1166e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1167e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1168e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1169054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1173054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1174fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1175fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1176fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1177fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1178fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1179fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1180fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1181fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1182fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1183fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1184fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1185fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1186fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1187fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1188fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1189fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1190fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1191fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1192fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1193fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1194fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1195fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1196fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1197fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1198fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1199fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1200fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1201fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1202fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1203fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1204fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
120584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1206fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1207fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1208fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1209fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1210fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1211fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1212fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1213e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1214e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                if (err == OK) {
1215e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-width", maxWidth);
1216e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-height", maxHeight);
1217e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("adaptive-playback", true);
1218e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
1219fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1220fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1221054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1222054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1223054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1224054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1225e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            inputFormat->setInt32("adaptive-playback", true);
1226054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
12270167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
12280167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
12290167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
12300167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
12310167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12320167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1233054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1234054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1235308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
124742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
124842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
124942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
125042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
125142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
125242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
125342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
125442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
125542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
125642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
125742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
125842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
125942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1266aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1267ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1268ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1269ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1270aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1271aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1272aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1273ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1274ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12754471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12764471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1278729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1280729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1282729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1283729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1284729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1285729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1286729de186450f78c099637e1fce743fe531862c52Andreas Huber
1287729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
13002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
13012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1302516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1303516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
13042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
13052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1306516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1307516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1308516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
13102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1311516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1312516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1313516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
13152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
13162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1317516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1318516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
13192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1320ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1321ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1322ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1323ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1324ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1325ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1326ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1327ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1328ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
132997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
133097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
133197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
133297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
133397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
133497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
133597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
133697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
133797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1339729de186450f78c099637e1fce743fe531862c52Andreas Huber
13404471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13414471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13424471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13434471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13448b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
13458b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
13468b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13479806555d3930be43e11106281dee354820ac1c88Andreas Huber
13488b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13498b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13508b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13518b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13529806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13539806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13549806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13559806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13569806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13579806555d3930be43e11106281dee354820ac1c88Andreas Huber
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1365e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1366e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1367e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1368e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1369e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1437aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1438aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1439ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1440ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1441ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1442ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1503aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
153997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
154097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
154197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
154297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
154397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
154497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
154597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
154697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
154797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
154897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
154997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
155097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
155197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
155297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
155397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
155497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
155597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
155697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
155797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
155897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
155997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
156097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
156197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
156297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
156397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
156497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
156597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
156697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
156797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
156897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
156997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
157097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
157197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
157297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
157397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
157497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
157597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
157697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1623729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1624729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1626729de186450f78c099637e1fce743fe531862c52Andreas Huber
1627729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1628729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1629729de186450f78c099637e1fce743fe531862c52Andreas Huber
1630729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1631729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1632729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1633729de186450f78c099637e1fce743fe531862c52Andreas Huber
1634729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1639729de186450f78c099637e1fce743fe531862c52Andreas Huber
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1643729de186450f78c099637e1fce743fe531862c52Andreas Huber
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1648729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1649729de186450f78c099637e1fce743fe531862c52Andreas Huber
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1656729de186450f78c099637e1fce743fe531862c52Andreas Huber
16572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
16802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
16812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
16822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1685729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1686729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1687729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1688729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1689729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1690729de186450f78c099637e1fce743fe531862c52Andreas Huber
1691729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1692729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1693729de186450f78c099637e1fce743fe531862c52Andreas Huber
1694729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1695729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1696729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1697729de186450f78c099637e1fce743fe531862c52Andreas Huber
1698729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1699729de186450f78c099637e1fce743fe531862c52Andreas Huber
1700729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1701729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1702729de186450f78c099637e1fce743fe531862c52Andreas Huber
1703729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1704729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1705729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1706729de186450f78c099637e1fce743fe531862c52Andreas Huber
1707729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1708729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1709729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1710729de186450f78c099637e1fce743fe531862c52Andreas Huber
1711729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1712729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1713729de186450f78c099637e1fce743fe531862c52Andreas Huber
1714729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1715729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1716729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1717729de186450f78c099637e1fce743fe531862c52Andreas Huber
1718729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1719729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1720729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1721729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1722729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1723729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1724729de186450f78c099637e1fce743fe531862c52Andreas Huber
1725c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1726c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1727729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1728729de186450f78c099637e1fce743fe531862c52Andreas Huber
1729729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1730729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1731729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1732729de186450f78c099637e1fce743fe531862c52Andreas Huber
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
181794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
181894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1847e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1848e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1850e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
203589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
203689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
203789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
203889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
203989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
20500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
20510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
20520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
20530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
20550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
20570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
20600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
20630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
20660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
20690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
20720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
20740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
20750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
20780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
20810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
20820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
20830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
209796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
209896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
209996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
210096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
210196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
210296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
210396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
210496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
210596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
211396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
211496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
217896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
219496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
219596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
225496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
227096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
227196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
22820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
22830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
23247c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
23257c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
23267c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
236896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
237189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
237289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
23734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
23744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
23754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
23764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
23774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
23784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
23794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
23804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
23814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
23824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
23834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
238489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
238589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
238689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
23874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
238889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
238989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
239089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
23924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
23934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
23944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
23954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
23964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
23974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
23984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
23994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
24004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
24014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
24024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
24034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
24044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
24054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
24064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
24074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
24084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
24094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
24104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
24114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
24124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
24134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
24154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
24164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
24174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
24184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
24194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
24204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
24214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
24224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
24234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
24244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
24254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
24264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
24284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
24294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
24304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
24314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
24324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
24334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
24344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
24364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
24374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
24384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
24404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
24414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
24424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
24434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
24444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
24454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
24464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
24474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
244889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
244989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
245089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
247796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
247896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
249196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2523f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2561f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2570d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2571d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2572d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2573d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2574d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2575d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2576d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2577d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2578d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2579d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2580d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2581d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2582d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2583d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
25847e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
25857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
25867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
25887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
25897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
25917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
25927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
25937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
25967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
25977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25987e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
25997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
26007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
26017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
26027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2603e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
26047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2605c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2606c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2607c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2608c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
26097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
26107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
26117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2612f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
26193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2634f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2639f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2649e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
2650e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
265131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
265231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
2653e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
265431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
265531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
265631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
265731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
265831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2659e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
2660e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
266131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
266231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
266331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
266431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
266531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2666e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
2667e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
2668e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2669e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
2670e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2671e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2672e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
2673e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
2674e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
2675e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2676e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
2677e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
2678e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    rect.nPortIndex = kPortIndexOutput;
2679e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2680e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
2681e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexConfigCommonOutputCrop,
2682e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
2683e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
2684e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
2685e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
2686e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
2687e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
268831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2689e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
2690e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
2691e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
2692e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
2693e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2694e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2696e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
2697577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2698577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2699577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2700e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
2701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
2702e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2703e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2704e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
2705e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
2706e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2707e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
2708e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
2709e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
2710e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
2711e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
2712e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
2713e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
2714e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
2715e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
271731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
2718e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2719e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
2720e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
272131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
272231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
272331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
272431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
272531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
272631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
272731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
272897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2733e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
274014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
274314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
274414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
274514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
274614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
274714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
274814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2749e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2750e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2751e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
27568b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
27588b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
27599806555d3930be43e11106281dee354820ac1c88Andreas Huber
2760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2764e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2765e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2766e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2773e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2777e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2778e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2781e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
27829806555d3930be43e11106281dee354820ac1c88Andreas Huber
2783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2796e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2807e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2818e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2820e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
2821e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2822e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
2823e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
2824e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2825e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2826e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
2827e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
2828e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
2829e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
2830e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2831e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
2832e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
2833e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
2834e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2835e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
2836e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2837e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
2838e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2839e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
2840e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
2841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
2844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
2845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
2846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
2847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
2849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
2850e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
2851e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2852e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
2853e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
285497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
285597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
285697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
285797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
2858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
285997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
286097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
286197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
286297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
286397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
286497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
286597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
286697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
286797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
286897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
286997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
287097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
2871e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2873e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
2874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
287631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
287731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
287831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
287931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
288031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
288131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
288231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2883e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
2884e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
2885e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2886e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
2887e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
2888e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
2889e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
2891e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2892e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
2893e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
2894e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2895e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
2896e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
2897e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
2898e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
2899e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
2900e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
2901e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
2902e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
2903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
2904e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
2905e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
2906e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
2907e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
2908e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
2909e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
2910e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
2911e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
2912e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
2913e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
2914e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
2915e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
2916e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
2917e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
2918e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
2919e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
292031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
292131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
292231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
292331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
292431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
29255778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2926cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2927cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2928cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2930cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2931cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2932cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2933bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2934bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2935bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2936bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2937bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2938bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2939bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2940bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2941bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2942bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2943bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2944bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2945bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2946bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2947bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2948bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2949bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2950bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2951bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2952bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2953bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2954bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2955bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2956bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2957bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2958bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2959bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2960bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2961bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2962bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2963bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2964bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2965bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
296687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
296787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
296887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
296987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
297087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
297187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2972bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2973bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2974bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2975bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2976bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2977bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2978bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2979bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2980bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2981bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2982bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2983bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2984bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2985bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2986bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2987bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2988bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2989bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2990bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2991bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2992bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2993bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2994bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2995bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2996bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2997bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2998bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2999bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3000bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3001bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3002bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
30031e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
30041e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3005bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3006bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3007bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3008bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3009bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3010bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3011bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3012bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3013bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3014bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3015bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3016bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3017bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3018bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3019bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3020bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3021bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3022bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3023bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3024bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3025bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3026bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3027bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3028bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3029bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3030bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3031bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
30321e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3033bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3034bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3035bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3036bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3037bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3038bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3039bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3040bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3041bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3042bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3043bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3044bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3045bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3046bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
30471e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3048bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3049bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3050bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3051bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3052bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3053bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3054bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3055bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3056bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3057bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3058bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3059bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3060bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3061bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3062bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3063bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3064bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3065bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3066bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3067bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3068bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3069bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3070bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3071bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3072bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3073bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3074bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3075bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3076bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3077bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3080eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3081eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3082eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3083496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3084496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3085496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3086496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3087496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3088496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3089496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3090496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3091496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3092496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3093496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3094496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3095496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3096496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3097496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3098496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3099496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3100496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3101eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3102eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3103eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3104eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3105eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3106eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3107eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3108eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3109eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3110eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3111eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3112eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3113eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3114eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3115eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3116eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3117eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3118eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3119eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3120eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3121f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3126ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3127ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
31517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
31527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
31537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
31547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
31557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
31567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
31577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3158ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3159ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3160ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3161ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3162ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3163ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3164ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31880af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
31890af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
31900af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
31910af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
31920af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
31930af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
31940af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
31950af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
31960af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
31970af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
31980af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
32483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3256cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
32623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3263349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3264349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
328096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
328196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
328296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
33222d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33382d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
33405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3341a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
33425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33432d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3344a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33477fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
33487fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
33497fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
33507fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
33517fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
33527fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
33537fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
33547fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
33553831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
33562d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
33605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
33615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
33625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
33635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3374dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3375dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3376dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3377dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
33965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
33975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
33985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3400d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3409078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
34103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3411078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
34125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
34135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
34145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3415078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3416d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3417d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3418d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3419d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
34203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3421078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3423078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3424349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3427d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3430d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3431d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3432054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3433054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3434054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3435054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3436054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3437054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3438054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3439054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3440054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3441054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3442054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3443054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3444054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3445054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
34585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
34595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
34605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
34615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
34625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
34645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
34655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3467dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
34683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3469dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3470dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3471dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
34723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3473dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3474dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3477349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3478349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3491dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3495625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3496625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3497625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3498625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3536ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        void * /* platformPrivate */,
3537ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        void * /* dataPtr */) {
35385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3540349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3542d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3543d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3549d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3550d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3551d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3552d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3553d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3554d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3555d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3556d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3557d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3563054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
35745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
35755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
35765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3577349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
35785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
35795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
35805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
35835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
358531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3586577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3587577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3588577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
35894bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3590577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3593308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3594308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3595308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3596308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3597308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3598308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3599308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3600308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3601308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3602496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
360321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3604496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3605496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3606496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
360821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36108b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
36118b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
36128b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
36182d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
36305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3634dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3664577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3665577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3666577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3667577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3668577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3669577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3670577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
36736aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
367479ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
36785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
36801e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3681cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3682cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3684cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3685cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3716c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
37173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3718c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3719349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3720c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3721c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3723c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3724c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3742f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3748ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3749ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3750ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3751ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3752ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3753ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3754ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3755ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3756ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3757ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3758ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3759308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3760ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3761c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3762c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
37765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
37775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
37785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3784c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3787c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3788c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3794c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3804c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3816c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3817c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3818c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3819c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
38205778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
38235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
38245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3825c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
38265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3832ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3833ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3834ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3835ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3836ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3837ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3838ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3839ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3840ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3841e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
38425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3846d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
38475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3848e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3849e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3850e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3851afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3852e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3853e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3854e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3855afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
38575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
38585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
38625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
38655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
38665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
38675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
38685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3869e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
38705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38711065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
38721065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
38731065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
38741065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
38751065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
38761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3877e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3878e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3880078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3881078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3882078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
38831065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3884078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
38871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
38881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
38891065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
38901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
38911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
38921065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3893c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
38965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
38975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
38985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
38995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3900c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3901cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3902c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3903c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3905ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3909ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3910ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3911ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3912ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
39130167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3914ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3915ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3916afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
39215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
39225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
39235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
39245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3926c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3927c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3928c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3929c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3932c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3933c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3934c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3935c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3936c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3937c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3938c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3939c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3940c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3941f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3942f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3943f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3944f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3945f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3946054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3947054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3948a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3949e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
3950e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
3951054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3952c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3953c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3954c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3955c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3956c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3957c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3958c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3959c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3960c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3961c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3962c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3963c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3964c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3965c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3966c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3967c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3968c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3969c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3970c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3971c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3972c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3973c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3974c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3975c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3976c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3977c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3978c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3979c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3980c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3981c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3982c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3983c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3984c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
39857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
39867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
39877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
39887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
39897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
39907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
39917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3992c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3993c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3994c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3995c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3996c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3997c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3998c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3999c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4000c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4001c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4002c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4003c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4004c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4005c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4007c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4008c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4009c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4010c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4011c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4012c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4013c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4014c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4015c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4016c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4017c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4018c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4019c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4020c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4021c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4022c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4023c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4024c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4025c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4026c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4028c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
40295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
40305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
40315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
40335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
40355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
40365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
40385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4040c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4041c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4042c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
40435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
4044c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4048386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
40495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
40501173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
40511173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
40521173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
40531173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
40541ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
40551ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
40561ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
40571ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
40625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
40635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
4064e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4065e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
40665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
40675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
40705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4073ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
40747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
40757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
40767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
40777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
40787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
40797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
40807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
40817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
40827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
40837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4084a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4085a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4086a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4087a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4088a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4089a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4090a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4091a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4092a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4093a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4094a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4095a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4096a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4097a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4098a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4099a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4100a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
41012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
410294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
410394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
410494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
410594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
410694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
410794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
410894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
410994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
411094ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
411172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
411272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
41132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
41142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
41152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
41162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
41172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
41182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
41192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
41202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
41212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
41222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
41232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
41242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
41252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
41262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
41272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
41282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
41292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
41302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
41312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
41322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
41332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
413472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
413572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
413672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
413772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
413872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
413972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
414072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
414172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
414272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
414372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
414472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
414572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
414694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
414794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
414894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
414994ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
415094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
41517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
41527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
41537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
41547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
41557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
41567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
41577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
41587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
41597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
41607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
41617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
41627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
41637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
41647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4165c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
41665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
41675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
41695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4177f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
41823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4184cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4185cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
418629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4187cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4188cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4189cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
419191bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
419291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4193cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
420872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
42166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
42176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
42186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
42196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
42206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
42216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
42226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
42236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
42246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
42256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
42266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
42276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
42286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
42296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
42306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
42316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
42326463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
42336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
42346463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
42356463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4265f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
42703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
427572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4282d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4283d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4284d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4285d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4286d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4287d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4288d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4289d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4290d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4291d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4292d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4293d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4294d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4295d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4296d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4297d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
42986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
42996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
43006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
43016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
43026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
43036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4330f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4331349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4335f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4336ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4340054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4341054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4342054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4343054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4344054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4345054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4346054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4347054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4348054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4349054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4350054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
43514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
43524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
43534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4354054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4355054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4356054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4372349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4373349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4381054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4382c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4383054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4384054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4385054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4386054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4387054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4389349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
43903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4391349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4392349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4393349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4394349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4395349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4403349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4404349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
44083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4419c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4420c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4421c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4422c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4423c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4424c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4425c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4426349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4427349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
44407a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4441d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4442d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4443d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4444d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4445d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4446d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4447d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4448349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4449349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4467496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4468496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4469496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4470496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4471496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4472496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4473496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4474496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4475496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4476496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4477496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4478a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4479a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4480a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4481a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4482a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4483a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4484a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4485a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4486a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4487a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4488a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4489a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4490a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4491a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4492a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4493a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4494a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
44957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
44967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
44976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
44987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
44997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
45007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
45017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
45024dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
45034dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
45044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
45054dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
45064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
45074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
45084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
45094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
45104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
45114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
45124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
45134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
45144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4523a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4524a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4525530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4526a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4527a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4528a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4529a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4530a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4531a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4532a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4533a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4534a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4535a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4536a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4537a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4538a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4539a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4540a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4541a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4542a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4543a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4544a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
454572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
454672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
454772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
454872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
454972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
455072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
455172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
455272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
455372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
455472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
455572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
455672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
455772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
455872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
455972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
456072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4561e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4562e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4563e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4564e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4565b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4566b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4567e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4568e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4569e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4570e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4571b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4572b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4573b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4574b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4575b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4576b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4577b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4578b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4579b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4580b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4581b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4582b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4583b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4584b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4585b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4586b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4587e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4588e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4589a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4590a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4591a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
45926507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
45936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
45946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
45956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
45966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
45976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
45986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
45996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
46006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
46016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
46026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
461031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4611054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4617349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
462031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
462131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
46233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4642f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4647f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4665349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4667349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
46683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4669349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4670349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
46853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4707cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4708cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4709cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
471029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4711cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4712cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4713cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
47145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4715d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4716755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4717755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4718755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4719755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4720755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4721755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4722755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4723755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4724cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
473031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
473131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
47323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4736349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4737349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4738349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4754f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
47555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
47565778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
47883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
478931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
47905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
479131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
48035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4809349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4810349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4811349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4812349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4813349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4814349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4815349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
48200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
48225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48300167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
48310167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4832bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4835bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4836bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4837bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4859f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4891f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
48923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4895f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4903c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4915f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
49203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
49527a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4953d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4954d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4963e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4964e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4965e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4966e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4967e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4979349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4980349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4981349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4982349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4983349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4984349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4985349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4986349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4987349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
49883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4989349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4990349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4991349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4992349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4993349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4994349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4995349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5003f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5009f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5015f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
50197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
50207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
50217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
50227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
5025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5030dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5031dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5032f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5033f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5034f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5035f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5041