ACodec.cpp revision 577db6d42b8d83b3578c7e56b1391bdaca9cb705
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
29f779bb50d9746d9526541c3e6dcdf619cac941b7Andy 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
3613315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber#include <media/hardware/HardwareAPI.h>
3713315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4003e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber#include "include/avc_utils.h"
4103e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1696610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
1706610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
1716610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        : mNotify(notify) {
1726610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    }
1736610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
1746610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
1756610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        mNotify->post();
1766610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    }
1776610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
1786610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huberprotected:
1796610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    virtual ~DeathNotifier() {}
1806610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
1816610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huberprivate:
1826610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    sp<AMessage> mNotify;
1836610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
1846610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
1856610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber};
1866610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1986610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    sp<DeathNotifier> mDeathNotifier;
1996610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
216f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
265349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
275349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
276349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
358afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
359afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
361c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
3629806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3639806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3649806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMask(0) {
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
368c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
381dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
400c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
401c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    msg->setMessage("params", params);
402c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    msg->post();
403c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber}
404c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
4055778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4115778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
417f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid ACodec::initiateCreateInputSurface() {
418f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
419f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
420f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
421f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid ACodec::signalEndOfInputStream() {
422f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
423f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
424f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
4255778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
429f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4307a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
438c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
441c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44403e2ffa64470eec4e886614a4fa4facbae58a862Andreas Hubervoid ACodec::signalRequestIDRFrame() {
44503e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
44603e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber}
44703e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = allocateOutputBuffersFromNativeWindow();
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
478ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
479ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
481afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
482afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
483afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
484afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4851065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
486ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
487ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
488ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
490ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
491ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
492ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
493ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
494ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(ptr, def.nBufferSize);
495ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
497ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
499ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
519eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
520eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
521eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
523eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
525eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
528eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
55329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5593c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5603c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5613c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5625ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5633c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5643c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5653c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
567bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
568bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
569bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
570bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
571bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
572bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
573bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
574bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
575bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
576bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
577bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
578bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
579bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
580bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
581bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
582bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
583bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
5923c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
59529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
599258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    int minUndequeuedBufs = 0;
600258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
601258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
602258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            &minUndequeuedBufs);
603258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
604258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
60529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
606258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
607258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
608258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
609258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
610258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
611258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
612258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
613258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
614258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
615258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
616258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
617258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
618258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
619258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
62029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
621258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
622258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
624258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
64074006804065941841883c4b46ee785070164023fJamie Gennis    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
6418ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6421e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
64429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
64974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
65074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
651616d9ea56744a9aeb3ae93e850450732acfe96a8Marco Nelissen        info.mData = new ABuffer(NULL /* data */, def.nBufferSize /* capacity */);
65274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
65374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
65474006804065941841883c4b46ee785070164023fJamie Gennis
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
65929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
66074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
66574006804065941841883c4b46ee785070164023fJamie Gennis
6663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
67874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Return the last two buffers to the native window.
681258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelEnd = def.nBufferCountActual;
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
7001e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
709f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
7108ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
7111e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
7121e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
71329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
714c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
715c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mGraphicBuffer->handle == buf->handle) {
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
746349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
751e532d37cf9342abbca398e4ce671b880369d90c6Lajos Molnar        // At this time some buffers may still be with the component
752e532d37cf9342abbca398e4ce671b880369d90c6Lajos Molnar        // or being drained.
753e532d37cf9342abbca398e4ce671b880369d90c6Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
754e532d37cf9342abbca398e4ce671b880369d90c6Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
782f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
8122944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
8132944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
8142944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
8152944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
822729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
823729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
824c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
825c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
826c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
827c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        { MEDIA_MIMETYPE_VIDEO_VPX,
8355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            "video_decoder.vpx", "video_encoder.vpx" },
836ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
837ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
8382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
8392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
8402ed5cf016c1b45426ae25ab105e02ff4bb992f28Marco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
8412ed5cf016c1b45426ae25ab105e02ff4bb992f28Marco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
8765ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
8885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
8895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
8905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
8915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
8965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
9022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
9032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
9042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
90835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    int32_t storeMeta;
90935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    if (encoder
91035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
91135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            && storeMeta != 0) {
91235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
91335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
91435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        if (err != OK) {
91535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
91635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                  mComponentName.c_str(), err);
91735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
91835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            return err;
91935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        }
92035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    }
92135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
92213315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber    int32_t prependSPSPPS;
92313315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber    if (encoder
92413315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
92513315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber            && prependSPSPPS != 0) {
92613315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber        OMX_INDEXTYPE index;
92713315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber        err = mOMX->getExtensionIndex(
92813315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber                mNode,
92913315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
93013315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber                &index);
93113315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber
93213315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber        if (err == OK) {
93313315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber            PrependSPSPPSToIDRFramesParams params;
93413315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber            InitOMXParams(&params);
93513315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber            params.bEnable = OMX_TRUE;
93613315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber
93713315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber            err = mOMX->setParameter(
93813315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber                    mNode, index, &params, sizeof(params));
93913315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber        }
94013315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber
94113315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber        if (err != OK) {
94213315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
94313315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber                  "IDR frames. (err %d)", err);
94413315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber
94513315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber            return err;
94613315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber        }
94713315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber    }
94813315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncasecmp(mime, "video/", 6)) {
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9612242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
9622242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber        int32_t numChannels, sampleRate;
9632242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
9642242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
9652242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber            // Since we did not always check for these, leave them optional
9662242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber            // and have the decoder figure it all out.
9672242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber            err = OK;
9682242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber        } else {
9692242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber            err = setupRawAudioFormat(
9702242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
9712242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber                    sampleRate,
9722242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber                    numChannels);
9732242fbd1d9327dff9c25ac2aba0fa7d5d471bb88Andreas Huber        }
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
980aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
981ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
982ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
983ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
984aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
985aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
986aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
987ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
988ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
989b81ed713b09d6db0f01d052fcd3f6bdfb5dd05c1Andreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
990b81ed713b09d6db0f01d052fcd3f6bdfb5dd05c1Andreas Huber                    isADTS != 0);
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
992729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
994729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
996729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
997729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
998729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
999729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1000729de186450f78c099637e1fce743fe531862c52Andreas Huber
1001729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
10082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
10092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
10102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
10112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
10122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
10132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
10142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
10152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1016e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber                if (!msg->findInt32(
1017e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber                            "flac-compression-level", &compressionLevel)) {
10182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
10192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1020e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1021e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber                          "using 0",
1022e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber                          compressionLevel);
10232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
10242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1025e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1026e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber                          "using 8",
1027e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber                          compressionLevel);
10282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
10292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
10302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1031e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber            err = setupFlacCodec(
1032e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
10332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1034ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1035ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1036ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1037ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1038ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1039ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1040ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1041ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1042ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1044729de186450f78c099637e1fce743fe531862c52Andreas Huber
1045b81ed713b09d6db0f01d052fcd3f6bdfb5dd05c1Andreas Huber    if (err != OK) {
1046b81ed713b09d6db0f01d052fcd3f6bdfb5dd05c1Andreas Huber        return err;
1047b81ed713b09d6db0f01d052fcd3f6bdfb5dd05c1Andreas Huber    }
1048b81ed713b09d6db0f01d052fcd3f6bdfb5dd05c1Andreas Huber
10498b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
10508b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
10518b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
10529806555d3930be43e11106281dee354820ac1c88Andreas Huber
10538b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
10548b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
10558b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
10568b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
10579806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
10589806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
10599806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
10609806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
10619806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
10629806555d3930be43e11106281dee354820ac1c88Andreas Huber
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1137aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1138aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1139ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1140ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1141ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1142ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1203aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1229ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1230ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1231ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1232ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1233ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
12655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1285729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1286729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1288729de186450f78c099637e1fce743fe531862c52Andreas Huber
1289729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1290729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1291729de186450f78c099637e1fce743fe531862c52Andreas Huber
1292729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1293729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1294729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1295729de186450f78c099637e1fce743fe531862c52Andreas Huber
1296729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1301729de186450f78c099637e1fce743fe531862c52Andreas Huber
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1305729de186450f78c099637e1fce743fe531862c52Andreas Huber
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1310729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1311729de186450f78c099637e1fce743fe531862c52Andreas Huber
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1315729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1316729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1317729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1318729de186450f78c099637e1fce743fe531862c52Andreas Huber
13192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
13202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
13212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
13222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
13232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
13242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
13252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
13262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
13272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
13282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
13292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
13302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
13312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
13322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
13332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
13342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
13352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
13362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
13372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
13382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
13392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
13402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
13412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
13422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
13432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
13442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
13452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
13462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1347729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1348729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1349729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1350729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1351729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1352729de186450f78c099637e1fce743fe531862c52Andreas Huber
1353729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1354729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1355729de186450f78c099637e1fce743fe531862c52Andreas Huber
1356729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1357729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1358729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1359729de186450f78c099637e1fce743fe531862c52Andreas Huber
1360729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1361729de186450f78c099637e1fce743fe531862c52Andreas Huber
1362729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1363729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1364729de186450f78c099637e1fce743fe531862c52Andreas Huber
1365729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1366729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1367729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1368729de186450f78c099637e1fce743fe531862c52Andreas Huber
1369729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1370729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1371729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1372729de186450f78c099637e1fce743fe531862c52Andreas Huber
1373729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1374729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1375729de186450f78c099637e1fce743fe531862c52Andreas Huber
1376729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1377729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1378729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1379729de186450f78c099637e1fce743fe531862c52Andreas Huber
1380729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1381729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1382729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1383729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1384729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1385729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1386729de186450f78c099637e1fce743fe531862c52Andreas Huber
1387c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1388c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1389729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1390729de186450f78c099637e1fce743fe531862c52Andreas Huber
1391729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1392729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1393729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1394729de186450f78c099637e1fce743fe531862c52Andreas Huber
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1471cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huberstatic const struct VideoCodingMapEntry {
1472cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    const char *mMime;
1473cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1474cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber} kVideoCodingMapEntry[] = {
1475cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1476cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1477cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1478cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
1479cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    { MEDIA_MIMETYPE_VIDEO_VPX, OMX_VIDEO_CodingVPX },
1480cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber};
1481cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1484cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    for (size_t i = 0;
1485cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1486cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber         ++i) {
1487cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1488cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1489cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            return OK;
1490cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber        }
1491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1493cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1494cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
1495cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    return ERROR_UNSUPPORTED;
1496cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber}
1497cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
1498cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huberstatic status_t GetMimeTypeForVideoCoding(
1499cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1500cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    for (size_t i = 0;
1501cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1502cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber         ++i) {
1503cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1504cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1505cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            return OK;
1506cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber        }
1507cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    }
1508cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
1509cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    mime->clear();
1510cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
1511cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber    return ERROR_UNSUPPORTED;
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1704e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
1705e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
1706e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    InitOMXParams(&params);
1707e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    params.nPortIndex = kPortIndexOutput;
1708e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong
1709e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
1710e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong
1711e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
1712e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
1713e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        int32_t mbs;
1714e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
1715e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong            return INVALID_OPERATION;
1716e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        }
1717e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        params.nCirMBs = mbs;
1718e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    }
1719e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong
1720e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
1721e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
1722e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        int32_t mbs;
1723e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
1724e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong            return INVALID_OPERATION;
1725e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        }
1726e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        params.nAirMBs = mbs;
1727e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong
1728e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        int32_t ref;
1729e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
1730e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong            return INVALID_OPERATION;
1731e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        }
1732e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        params.nAirRef = ref;
1733e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    }
1734e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong
1735e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    status_t err = mOMX->setParameter(
1736e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong            mNode, OMX_IndexParamVideoIntraRefresh,
1737e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong            &params, sizeof(params));
1738e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    return err;
1739e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong}
1740e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17527b4262221c06951e9df75d5414c0a7daab365177Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
17537b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    int32_t tmp;
17547b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
17557b4262221c06951e9df75d5414c0a7daab365177Andreas Huber        return OMX_Video_ControlRateVariable;
17567b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    }
17577b4262221c06951e9df75d5414c0a7daab365177Andreas Huber
17587b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
17597b4262221c06951e9df75d5414c0a7daab365177Andreas Huber}
17607b4262221c06951e9df75d5414c0a7daab365177Andreas Huber
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17687b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
17697b4262221c06951e9df75d5414c0a7daab365177Andreas Huber
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18337b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18497b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
18507b4262221c06951e9df75d5414c0a7daab365177Andreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19097b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19257b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
19267b4262221c06951e9df75d5414c0a7daab365177Andreas Huber
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1936e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    status_t err = OK;
1937e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    int32_t intraRefreshMode = 0;
1938e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
1939e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
1940e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        if (err != OK) {
1941e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
1942e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong                    err, intraRefreshMode);
1943e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong            return err;
1944e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong        }
1945e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    }
1946e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1951e97adde42fabc3928a2ac0b8cdc88e35b24b85dcJames Dong    err = mOMX->getParameter(
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
19797c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
19807c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
19817c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20237b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    return configureBitrate(bitrate, bitrateMode);
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20527b4262221c06951e9df75d5414c0a7daab365177Andreas Huberstatus_t ACodec::configureBitrate(
20537b4262221c06951e9df75d5414c0a7daab365177Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20667b4262221c06951e9df75d5414c0a7daab365177Andreas Huber    bitrateType.eControlRate = bitrateMode;
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2098f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2145d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2146d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2147d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2148d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2149d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2150d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2151d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2152d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2153d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2154d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2155d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2156d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2157d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2158d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
21590ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
21600ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    size_t n = 0;
21610ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
21620ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
21630ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
21640ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
21650ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
21660ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber            ++n;
21670ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber        }
21680ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    }
21690ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
21700ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    return n;
21710ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber}
21720ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
21730ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
21740ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    if (mNativeWindow == NULL) {
21750ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber        return;
21760ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    }
21770ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
21780ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    int minUndequeuedBufs = 0;
21790ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    status_t err = mNativeWindow->query(
21800ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
21810ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber            &minUndequeuedBufs);
21820ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
21830ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    if (err != OK) {
21840ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
21850ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
21860ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
21870ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber        minUndequeuedBufs = 0;
21880ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    }
21890ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
21900ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
21910ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
21920ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber    }
21930ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber}
21940ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
2195f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
22023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2212f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2217f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2222f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2232577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
223331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
223431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
223531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
223631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
223731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
223831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
223931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
224031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
224131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
224231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
224331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
224431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
224531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
224631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
224731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
224831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
224931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
225031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2251cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            AString mime;
2252cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            if (!mIsEncoder) {
2253cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2254cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            } else if (GetMimeTypeForVideoCoding(
2255cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2256cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                notify->setString("mime", "application/octet-stream");
2257cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            } else {
2258cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                notify->setString("mime", mime.c_str());
2259cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            }
2260cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
226131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
226231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
226331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2264cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            if (!mIsEncoder) {
2265cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                notify->setInt32("stride", videoDef->nStride);
2266cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2267cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2268cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2269cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                OMX_CONFIG_RECTTYPE rect;
2270cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                InitOMXParams(&rect);
2271cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                rect.nPortIndex = kPortIndexOutput;
2272cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2273cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                if (mOMX->getConfig(
2274cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2275cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                            &rect, sizeof(rect)) != OK) {
2276cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    rect.nLeft = 0;
2277cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    rect.nTop = 0;
2278cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2279cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2280cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                }
2281cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2282cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                CHECK_GE(rect.nLeft, 0);
2283cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                CHECK_GE(rect.nTop, 0);
2284cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                CHECK_GE(rect.nWidth, 0u);
2285cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                CHECK_GE(rect.nHeight, 0u);
2286cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2287cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2288cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2289cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                notify->setRect(
2290cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        "crop",
2291cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        rect.nLeft,
2292cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        rect.nTop,
2293cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        rect.nLeft + rect.nWidth - 1,
2294cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        rect.nTop + rect.nHeight - 1);
2295cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2296cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                if (mNativeWindow != NULL) {
2297577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2298577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2299577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2300577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2301577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2302577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2303cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                }
230431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
230531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
230631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
230731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
230831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
230931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
231031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
231131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2312cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            switch (audioDef->eEncoding) {
2313cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                case OMX_AUDIO_CodingPCM:
2314cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                {
2315cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2316cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    InitOMXParams(&params);
2317cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    params.nPortIndex = kPortIndexOutput;
2318cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2319cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    CHECK_EQ(mOMX->getParameter(
2320cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                mNode, OMX_IndexParamAudioPcm,
2321cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                &params, sizeof(params)),
2322cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                             (status_t)OK);
2323cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2324cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2325cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
2326cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
2327cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
2328cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2329cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2330cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setInt32("channel-count", params.nChannels);
2331cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2332cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2333cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2334cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        if (mSkipCutBuffer != NULL) {
2335cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2336cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                            if (prevbufsize != 0) {
2337cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbufsize);
2338cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                            }
2339cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        }
2340cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay * frameSize,
2341cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                                           mEncoderPadding * frameSize);
2342cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    }
2343cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2344cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    if (mChannelMaskPresent) {
2345cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        notify->setInt32("channel-mask", mChannelMask);
23468b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2347cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    break;
23488b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
23499806555d3930be43e11106281dee354820ac1c88Andreas Huber
2350cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                case OMX_AUDIO_CodingAAC:
2351cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                {
2352cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2353cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    InitOMXParams(&params);
2354cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    params.nPortIndex = kPortIndexOutput;
2355cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2356cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    CHECK_EQ(mOMX->getParameter(
2357cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                mNode, OMX_IndexParamAudioAac,
2358cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                &params, sizeof(params)),
2359cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                             (status_t)OK);
2360cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2361cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2362cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setInt32("channel-count", params.nChannels);
2363cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2364cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    break;
2365cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                }
2366cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2367cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                case OMX_AUDIO_CodingAMR:
2368cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                {
2369cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2370cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    InitOMXParams(&params);
2371cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    params.nPortIndex = kPortIndexOutput;
23729806555d3930be43e11106281dee354820ac1c88Andreas Huber
2373cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    CHECK_EQ(mOMX->getParameter(
2374cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                mNode, OMX_IndexParamAudioAmr,
2375cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                &params, sizeof(params)),
2376cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                             (status_t)OK);
2377cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2378cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setInt32("channel-count", 1);
2379cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2380cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        notify->setString(
2381cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2382cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2383cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        notify->setInt32("sample-rate", 16000);
2384cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    } else {
2385cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        notify->setString(
2386cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2387cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2388cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                        notify->setInt32("sample-rate", 8000);
2389cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    }
2390cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    break;
2391cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                }
2392cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2393cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                case OMX_AUDIO_CodingFLAC:
2394cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                {
2395cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2396cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    InitOMXParams(&params);
2397cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    params.nPortIndex = kPortIndexOutput;
2398cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2399cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    CHECK_EQ(mOMX->getParameter(
2400cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                mNode, OMX_IndexParamAudioFlac,
2401cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                                &params, sizeof(params)),
2402cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                             (status_t)OK);
2403cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2404cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2405cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setInt32("channel-count", params.nChannels);
2406cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2407cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    break;
2408cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                }
2409cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber
2410cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                default:
2411cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber                    TRESPASS();
2412cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            }
241331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
241431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
241531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
241631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
241731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
241831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
241931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
242031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
242131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
242231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
242331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
242431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
24255778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2426cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2427cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2428cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2430cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2431cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2432cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2433bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2434bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2435bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2436bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2437bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2438bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2439bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2440bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2441bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2442bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2443bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2444bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2445bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2446bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2447bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2448bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2449bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2450bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2451bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2452bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2453bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2454bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2455bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2456bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2457bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2458bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2459bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2460bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2461bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2462bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2463bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2464bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2465bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2466bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2467bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2468bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2469bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2470bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2471bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2472bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2473bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2474bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2475bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2476bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2477bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2478bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2479bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2480bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2481bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2482bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2483bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2484bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2485bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2486bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2487bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2488bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2489bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2490bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2491bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2492bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2493bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2494bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
24951e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
24961e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2497bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2498bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2499bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2500bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2501bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2502bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2503bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2504bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2505bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2506bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2507bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2508bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2509bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2510bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2511bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2512bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2513bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2514bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2515bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2516bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2517bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2518bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2519bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2520bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2521bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2522bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2523bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
25241e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2525bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2526bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2527bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2528bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2529bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2530bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2531bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2532bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2533bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2534bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2535bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2536bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2537bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2538bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
25391e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2540bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2541bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2542bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2543bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2544bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2545bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2546bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2554bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2555bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2556bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2557bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2558bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2559bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2560bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2561bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2562bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2563bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2564bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2565bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2566bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2567bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2568bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2569bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2572eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2573eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2574eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
257503e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huberstatus_t ACodec::requestIDRFrame() {
257603e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    if (!mIsEncoder) {
257703e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber        return ERROR_UNSUPPORTED;
257803e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    }
257903e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
258003e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
258103e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    InitOMXParams(&params);
258203e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
258303e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    params.nPortIndex = kPortIndexOutput;
258403e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
258503e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
258603e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    return mOMX->setConfig(
258703e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            mNode,
258803e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
258903e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            &params,
259003e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            sizeof(params));
259103e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber}
259203e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
2593eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2594eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2595eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2596eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2597eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2598eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2599eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2600eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2601eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2602eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2603eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2604eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2605eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2606eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2607eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2608eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2609eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2610eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2611eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2612eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2613f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2618f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2641f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        case ACodec::kWhatCreateInputSurface:
2642f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        case ACodec::kWhatSignalEndOfInputStream:
2643f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        {
2644f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
2645f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
2646f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            return true;
2647f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
2648f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
26496610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        case ACodec::kWhatOMXDied:
26506610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        {
26516610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
26526610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
26536610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber            break;
26546610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        }
26556610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2663f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26790af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
26800af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
26810af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
26820af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
26830af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
26840af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
26850af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
26860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
26870af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
26880af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
26890af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
27393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2747cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2752f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
27533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2754349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2755349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
276335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    void *mediaBuffer;
276435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
276535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            && mediaBuffer != NULL) {
276635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
276735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        // OMX component had access to data that's implicitly refcounted
276835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
276935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        // told us that it's done with the input buffer, we can decrement
277035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        // the mediaBuffer's reference count.
2771a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
2772a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
2773a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
277435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
277535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        mediaBuffer = NULL;
277635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
277735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
277835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    }
277935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
2780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
28132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
2821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28292d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
2830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28332d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
2834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
28373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
28383831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
28392d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
2842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
2851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
2852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
2861dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
2862dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
2863dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
2864dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
288735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
288835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                         mCodec->mComponentName.c_str(),
288935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                         bufferID,
289035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                         buffer.get(), info->mData.get());
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2896078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
28973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
2898078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
2902078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
290335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#if TRACK_BUFFER_TIMING
290435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
290535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
290635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#else
29073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
2908078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
290935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#endif
2910078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
2911349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
291235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#if TRACK_BUFFER_TIMING
291335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                ACodec::BufferStats stats;
291435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
291535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
291635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
291735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#endif
291835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
2940dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
29413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
2942dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
2943dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
2944dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
29453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
2946dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
2947dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
2950349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
2951349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
2964dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
30115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
30125778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3013349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
301535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
301635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#if TRACK_BUFFER_TIMING
301735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
301835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    if (index >= 0) {
301935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
302035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
302135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
302235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        ALOGI("frame PTS %lld: %lld",
302335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                timeUs,
302435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
302535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
302635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
302735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        stats = NULL;
302835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    }
302935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#endif
303035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
30475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
30485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3049349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
30505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
30555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
30565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
305731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3058577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3059577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3060577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3061cd4ac42ed448f1cb286ca4c3c7ea64621adf9d42Andreas Huber            if (!mCodec->mSentFormat) {
3062577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3065616d9ea56744a9aeb3ae93e850450732acfe96a8Marco Nelissen            info->mData->setRange(rangeOffset, rangeLength);
306603e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber#if 0
3067616d9ea56744a9aeb3ae93e850450732acfe96a8Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
306803e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber                if (IsIDR(info->mData)) {
306903e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber                    ALOGI("IDR frame");
307003e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber                }
30715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3072616d9ea56744a9aeb3ae93e850450732acfe96a8Marco Nelissen#endif
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
30758b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
30768b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
30775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
30822d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
30835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
30905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
30945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
30955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3098dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3128577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3129577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3130577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3131577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3132577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3133577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3134577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
3137b6ac8e2ce3574160714fd3c0c6d6b5fbf6c8eeabMarco Nelissen            && msg->findInt32("render", &render) && render != 0
3138b6ac8e2ce3574160714fd3c0c6d6b5fbf6c8eeabMarco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
31441e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3145cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3146cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
31475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3148cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3149cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3180c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
31813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3182c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3183349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3184c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3185c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3187c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3188c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3206f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
32126610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
32136610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    if (mDeathNotifier != NULL) {
32146610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
32156610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        mDeathNotifier.clear();
32166610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    }
32176610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
32186610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    mCodec->mNativeWindow.clear();
32196610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    mCodec->mNode = NULL;
32206610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    mCodec->mOMX.clear();
32216610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    mCodec->mQuirks = 0;
32226610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    mCodec->mFlags = 0;
32236610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    mCodec->mComponentName.clear();
3224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
32395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
32405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
32415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
32425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
32435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3248c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3257c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3267c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
32835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3285c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
32865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
32875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
32895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32956610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
32966610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
32976610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
32986610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
32996610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        // This was a local binder, if it dies so do we, we won't care
33006610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        // about any notifications in the afterlife.
33016610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber        mDeathNotifier.clear();
33026610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    }
33036610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber
3304e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
33055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
330935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    uint32_t quirks = 0;
33105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3311e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3312e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3313e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3314afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3315e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3316e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3317e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3318afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
33195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
33205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
33215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
33235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
33245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
33255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
33285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
33295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
33305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
33315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3332e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
33335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
33351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
33361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
33371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
33381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
33391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3340e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3341e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3343078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3344078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3345078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
33461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3347078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33491065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
33501065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
33511065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
33521065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
33531065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
33541065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
33551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3356c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
33575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
33585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
33595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
33605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
33615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
33625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3363c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3364cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3366c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33686610a7d621c634fe059b855ca7eb3f58fb8d0757Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3372ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3373ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3374ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3375ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
3376ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3377ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3378afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
33835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
33845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
33855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
33865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
33875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3388c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3389c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3390c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3391c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
33925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3394c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3395c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3396c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3397c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
340316572becd56c43a43ceffd8edd33263895d0c045Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
340416572becd56c43a43ceffd8edd33263895d0c045Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
340516572becd56c43a43ceffd8edd33263895d0c045Andreas Huber
340616572becd56c43a43ceffd8edd33263895d0c045Andreas Huber    mCodec->mInputEOSResult = OK;
340716572becd56c43a43ceffd8edd33263895d0c045Andreas Huber
3408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3409c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3411c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3412c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3413c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3414c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3415c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3416c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3417c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3418c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3419c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3420c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3421c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3422c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3423c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3424c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3425c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3426c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3428c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3431c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3432c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3433c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3434c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3435c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3436c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3437c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3438c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3441f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        case ACodec::kWhatCreateInputSurface:
3442f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        {
3443f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            onCreateInputSurface(msg);
3444f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            handled = true;
3445f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            break;
3446f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
3447f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3451c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3456c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3457c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3458c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3459c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3460c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3461c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3462c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3463c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3464c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3465c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3466c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3467c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3468c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3472c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3473c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3474c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3475c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3476c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3477c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3478c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3480c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3482c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3484c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
34855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
34865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
34875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
34895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
34915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
34925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
34945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3496c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3497c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3498c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
34995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
35015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3504386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
35055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
35061173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
35071173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
35081173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
35091173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
35101ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
35111ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
35121ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
35131ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
35185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
35195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3522c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3523c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
35245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3526f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
3527f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        const sp<AMessage> &msg) {
3528f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    ALOGV("onCreateInputSurface");
3529f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3530f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
3531f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
3532f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3533f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<IGraphicBufferProducer> bufferProducer;
3534f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err;
3535f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3536f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
3537f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            &bufferProducer);
3538f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err == OK) {
3539f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        notify->setObject("input-surface",
3540f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                new BufferProducerWrapper(bufferProducer));
3541f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    } else {
3542f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
3543f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // the error through because it's in the "configured" state.  We
3544f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
3545f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
3546f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden                mCodec->mComponentName.c_str(), err);
3547f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        notify->setInt32("err", err);
3548f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
3549f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    notify->post();
3550f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
3551f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3552c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
35545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
35565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3564f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
35693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3571cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3572cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
357329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3574cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3575cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3576cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
357891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
357991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3580cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3601ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        case kWhatSignalEndOfInputStream:
3602ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        {
3603ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden            mCodec->onSignalEndOfInputStream();
3604ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden            return true;
3605ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        }
3606ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
3607488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen        case kWhatResume:
3608488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen        {
3609488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen            // We'll be active soon enough.
3610488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen            return true;
3611488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen        }
3612488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen
3613488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen        case kWhatFlush:
3614488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen        {
3615488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen            // We haven't even started yet, so we're flushed alright...
3616488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
3617488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3618488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen            notify->post();
3619488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen            return true;
3620488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen        }
3621488bf2281134c549fcc9ffcec7bda9690c2d5617Marco Nelissen
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3651f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
36563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36675e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber        case kWhatResume:
36685e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber        {
36695e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber            // We'll be active soon enough.
36705e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber            return true;
36715e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber        }
36725e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber
36735e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber        case kWhatFlush:
36745e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber        {
36755e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber            // We haven't even started yet, so we're flushed alright...
36765e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
36775e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
36785e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber            notify->post();
36795e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber
36805e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber            return true;
36815e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber        }
36825e691cd3aed18b79cc7362b6689f67886ce90e56Andreas Huber
3683ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        case kWhatSignalEndOfInputStream:
3684ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        {
3685ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden            mCodec->onSignalEndOfInputStream();
3686ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden            return true;
3687ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        }
3688ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3715f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3716349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3717349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3720f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::submitOutputBuffers() {
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3741349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3742349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
3751349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
37523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
3753349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
3754349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3755349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
3756349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
3757349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
3765349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3766349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
37703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3783c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3784c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
3786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
3787c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3788349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3789349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
38027a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
3803d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
3804d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
3805d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
3806d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
3807d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
3808d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
3809d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3810349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3811349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382903e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber        case kWhatRequestIDRFrame:
383003e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber        {
383103e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            status_t err = mCodec->requestIDRFrame();
383203e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            if (err != OK) {
383303e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber                ALOGW("Requesting an IDR frame failed.");
383403e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            }
383503e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
383603e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            handled = true;
383703e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber            break;
383803e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber        }
383903e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
3840c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        case kWhatSetParameters:
3841c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        {
3842c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            sp<AMessage> params;
3843c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            CHECK(msg->findMessage("params", &params));
3844c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
3845c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            status_t err = mCodec->setParameters(params);
3846c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
3847c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            sp<AMessage> reply;
3848c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            if (msg->findMessage("reply", &reply)) {
3849c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber                reply->setInt32("err", err);
3850c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber                reply->post();
3851c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            }
3852c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
3853c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            handled = true;
3854c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            break;
3855c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        }
3856c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
3857f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        case ACodec::kWhatSignalEndOfInputStream:
3858f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        {
3859ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden            mCodec->onSignalEndOfInputStream();
3860f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            handled = true;
3861f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            break;
3862f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        }
3863f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3872c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
3873c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    int32_t videoBitrate;
3874c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    if (params->findInt32("videoBitrate", &videoBitrate)) {
3875c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
3876c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        InitOMXParams(&configParams);
3877c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        configParams.nPortIndex = kPortIndexOutput;
3878c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        configParams.nEncodeBitrate = videoBitrate;
3879c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
3880c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        status_t err = mOMX->setConfig(
3881c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber                mNode,
3882c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber                OMX_IndexConfigVideoBitrate,
3883c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber                &configParams,
3884c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber                sizeof(configParams));
3885c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
3886c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        if (err != OK) {
3887c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
3888c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber                   videoBitrate, err);
3889c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
3890c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber            return err;
3891c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber        }
3892c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    }
3893c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
3894c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber    return OK;
3895c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber}
3896c71601c3b1dd63afc9be462194809813e4dbacf1Andreas Huber
3897ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
3898ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    sp<AMessage> notify = mNotify->dup();
3899ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
3900ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
3901ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
3902ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    if (err != OK) {
3903ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        notify->setInt32("err", err);
3904ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    }
3905ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    notify->post();
3906ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden}
3907ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3921349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
392431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
392531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
39273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3946f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3951f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3969349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3971349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
39723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
3973349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
3974349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
39893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4011cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4012cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4013cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
401429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4015cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4016cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4017cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
40185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4019d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4020755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4021755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4022755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4023755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4024755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4025755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4026755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4027755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4028cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
403531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
40363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4039349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4040349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4041349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4042349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4058f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
40595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
40605778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
40923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
409331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
40945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
409531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
41075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4113349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4114349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4115349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4116349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4117349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4118349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4119349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
41240af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
41265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4134bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
4135bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4136bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4137bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4138bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4139bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4140bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4141bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4162f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
41953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4218f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
42233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
42557a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4256d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4257d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4266e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4267e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4268e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4269e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4270e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4283349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4284349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4285349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4286349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4287349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4288349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4289349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4290349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
42913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4292349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4293349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4294349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4295349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4296349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4297349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4298349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
43220ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber        // We now own all buffers except possibly those still queued with
43230ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber        // the native window for rendering. Let's get those back as well.
43240ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
43250ae2001f40587556e2f5ed56f791292fb5e9a329Andreas Huber
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4333dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4334dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4335b3ac921cae96686ec0902796bb8f8ef99ae08abdMarco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4336b3ac921cae96686ec0902796bb8f8ef99ae08abdMarco Nelissen            mCodec->mSkipCutBuffer->clear();
4337b3ac921cae96686ec0902796bb8f8ef99ae08abdMarco Nelissen        }
4338b3ac921cae96686ec0902796bb8f8ef99ae08abdMarco Nelissen
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4344