ACodec.cpp revision d0b9a2b8538c9e4538d92fd675cf6786644ccb85
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
35a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
38afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
56251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
97f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
118609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
131609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
137609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
205784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
304054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
312349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
313349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
322349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
406609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
409308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4109806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4129806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4139806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
414e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4159806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
416054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
417054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
419a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42094ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
4222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
423609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
424ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
425ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
440dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
459a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
460a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
462a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
463a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4645778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4897a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
493f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
50130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
50230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
50330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, id()))->post(3000000);
50430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
507496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
508496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
509496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
510496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
5204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
531054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
532054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
533054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
534054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
535054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
545609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
558ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
560afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
561afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
562afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
563afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
565308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
566308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
569ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
570ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
571ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
572ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
573ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
574308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
575308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
576308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
577308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
578ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
580ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
582ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
583ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
584ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
585ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
586ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
599d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
602eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
603eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
604eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
606eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
608eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
617054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
643e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
644e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
645e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
646e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
647e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
648e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
649e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
650e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
651e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
652e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
653e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
654e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
655e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
659e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
660e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
661e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
662e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
663e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6653c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6673c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6693c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6703c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6713c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6723c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6983c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
70129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
706ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
707ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
708ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
709ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
710ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
711ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
712ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
713ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
714ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
715ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
716ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
717ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
718ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
719ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
720054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
721258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
722258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
724258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
725258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
72629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
727258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
728258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
729258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
730258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
731e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
732e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7331faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7341faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
735e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
736e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
737e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
738e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
739e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
740e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
741e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7421faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7431faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
744e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
745e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
746258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
747258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
748258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
749258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
750e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
751e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
752e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
753e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
754e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
755609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
756e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
757e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
758e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
759258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
760258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
761258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
762258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
76729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
783e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
785609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7918ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7921e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
79429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
79974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
80074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
80274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
80374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
80474006804065941841883c4b46ee785070164023fJamie Gennis
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
809609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
81074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
81574006804065941841883c4b46ee785070164023fJamie Gennis
816609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
82874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8373fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8383fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8393fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8403fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
852e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
854609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
856054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
874054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
875054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
878609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
895609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
900054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
902054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
903054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
904054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
909609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
9131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9153fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
9163fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9203fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
923f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9248ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
9251e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
927ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
928ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
929ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
930ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
931ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
932ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
933ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
9341e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
93529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
936c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
937c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
944054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
955054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
956054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
958054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
959054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
960054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
961054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
962054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
963054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
964054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
965054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
966054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
968054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
970d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
971d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
972d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
974d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
975d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
976d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
977d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
978d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
979d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
982d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
983d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
984054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
985054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10082ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
10092ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
10102ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
10112ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
10273fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1039f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
10692944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
10702944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
10712944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
10722944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1079729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1080729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1081bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1082bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1083c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1084c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1085c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1086c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
10892472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
10902472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
109594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
109694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
109794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
109894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1099ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1100ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
11012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
11022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1103ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1104ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1105774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1106774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
110797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
110897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11435ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
11614e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1162e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1185308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1186308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1188308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1189308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1190308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1192308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
11933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
11943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
11953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
11963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
11973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
11983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
12003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
12013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
12033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
12043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
12053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
12063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
12083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
12093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
12123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
12133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
12143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
12163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
12183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1219308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1220308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1221308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1222308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1223308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1224308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1225308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1226308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1227308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1228308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1229308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1230308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1231308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1232308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1233308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1234308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1235308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1236308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1237a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1238a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1239a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1240a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1241a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1242a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
124394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
124494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
12482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
125094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
125172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
125272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
125372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
125472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
125572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
125672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1257308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1258308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
12615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        obj != NULL;
1262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1263e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1264e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1265e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1266054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
12675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<NativeWindowWrapper> windowWrapper(
12685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                static_cast<NativeWindowWrapper *>(obj.get()));
12695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
12705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12716597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
12726597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
12736597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
12746597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
12756597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
12766597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
12776597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
12786597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
12796597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
12806597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
12816597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
12826597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
12836597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
12846597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
12856597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
12866597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
12876597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
12886597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
12895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
12905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
12915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
12925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1293ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
12945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
129597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
129697827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
12975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
12985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
12995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
13005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
130197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
13025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
13035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1304fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1305fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1306d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1307d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1308d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1309d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1310d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1311d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1312d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1313d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1314d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
1315d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1316d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1317d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1318d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1319d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1320d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
13215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1322ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1323ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1324ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
13255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
13265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
13275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
13285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
13295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1330fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1331e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
13335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
13345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
13355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
13375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
13385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
13395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
13405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
13415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
13435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
13445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
13455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
13465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
13475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
13485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
13495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
13505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
13515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
13525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
13535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
13555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
13565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
13575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
13585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
13595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
13605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
13625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
13635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
13645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
13655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
13665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
13675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
13695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
13705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
13715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
13725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1373e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
13745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
13755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
13765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
13775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
13785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
13795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
13805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1381fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
13820167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
13835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
13845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
13855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
13865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
13875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13880167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1389e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1390e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1391e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1392e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1393e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1394e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1395e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1396054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1397054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1398308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
140289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setupVideoDecoder(mime, msg);
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
140442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
140542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
140642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
140742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
140842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
140942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
141042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
141142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
141242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
141342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
141442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
141542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
141642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1423aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1424b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
14258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
14262965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
14278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1428ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1429ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1430ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1431aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1432aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1433aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1434b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1435b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1436b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1437ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14388045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
14398045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
14408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14412965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
14422965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
14432965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
14442965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
14458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
14468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
14488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
14508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
14528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
14548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
14568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
14588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
14608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
14628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
14638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
14648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
14658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1466ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
14674471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
14682965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
14692965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1471729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1473729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1475729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1476729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1477729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1478729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1479729de186450f78c099637e1fce743fe531862c52Andreas Huber
1480729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
14872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
14882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
14892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
14902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
14912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
14922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
14932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
14942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1495516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1496cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1497cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1498516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1499cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
15002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1501516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1502516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1503516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
15042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
15052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1506516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1507516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1508516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
15092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
15102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
15112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1512516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1513516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
15142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1515ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1516ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1517ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1518ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1519ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1520ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1521ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1522ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1523ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
152497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
152597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
152697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
152797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
152897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
152997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
153097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
153197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
153297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1534729de186450f78c099637e1fce743fe531862c52Andreas Huber
15354471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
15364471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
15374471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
15384471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
15398b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
15408b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
15418b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15429806555d3930be43e11106281dee354820ac1c88Andreas Huber
15438b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
15448b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
15458b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
15468b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
15479806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
15489806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
15499806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
15509806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
15519806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
15529806555d3930be43e11106281dee354820ac1c88Andreas Huber
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15604e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
15614e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1562e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1563e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1564e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1565e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1566e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1634aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
16358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
16362965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
16372965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1638ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1639ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1640ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1641ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1702aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1704b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1705b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1706b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1707b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1708b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1709b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1710b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1711b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1712b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1713b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1714b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1715b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1716b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1717b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1718b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1719b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1720b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1721b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1722b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1723b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1724b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1725b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1726b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1727b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1728b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1729b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1754ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1755ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1756ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1757ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1758ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
17618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
17628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
17638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
17648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
17658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
17668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
17672965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
17688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
17698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
17708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
17718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
17728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
17738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
17748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
17758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
17768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
17778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
178097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
178197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
178297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
178397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
178497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
178597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
178697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
178797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
178897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
178997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
179097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
179197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
179297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
179397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
179497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
179597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
179697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
179797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
179897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
179997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
180097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
180197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
180297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
180397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
180497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
180597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
180697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
180797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
180897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
180997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
181097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
181197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
181297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
181397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
181497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
181597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
181697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
181797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1864729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1865729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1867729de186450f78c099637e1fce743fe531862c52Andreas Huber
1868729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1869729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1870729de186450f78c099637e1fce743fe531862c52Andreas Huber
1871729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1872729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1873729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1874729de186450f78c099637e1fce743fe531862c52Andreas Huber
1875729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1880729de186450f78c099637e1fce743fe531862c52Andreas Huber
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1884729de186450f78c099637e1fce743fe531862c52Andreas Huber
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1889729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1890729de186450f78c099637e1fce743fe531862c52Andreas Huber
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1894729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1895729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1896729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1897729de186450f78c099637e1fce743fe531862c52Andreas Huber
18982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
18992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
19002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
19012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
19022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
19032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
19042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
19052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
19062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
19072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
19082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
19092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
19102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
19112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
19122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
19132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
19142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
19152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
19162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
19172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
19182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
19192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
19202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
19212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
19222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
19232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
19242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
19252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1926729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1927729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1928729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1929729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1930729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1931729de186450f78c099637e1fce743fe531862c52Andreas Huber
1932729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1933729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1934729de186450f78c099637e1fce743fe531862c52Andreas Huber
1935729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1936729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1937729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1938729de186450f78c099637e1fce743fe531862c52Andreas Huber
1939729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1940729de186450f78c099637e1fce743fe531862c52Andreas Huber
1941729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1942729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1943729de186450f78c099637e1fce743fe531862c52Andreas Huber
1944729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1945729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1946729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1947729de186450f78c099637e1fce743fe531862c52Andreas Huber
1948729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1949729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1950729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1951729de186450f78c099637e1fce743fe531862c52Andreas Huber
1952729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1953729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1954729de186450f78c099637e1fce743fe531862c52Andreas Huber
1955729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1956729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1957729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1958729de186450f78c099637e1fce743fe531862c52Andreas Huber
1959729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1960729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1961729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1962729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1963729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1964729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1965729de186450f78c099637e1fce743fe531862c52Andreas Huber
1966c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1967c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1968729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1969729de186450f78c099637e1fce743fe531862c52Andreas Huber
1970729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1971729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1972729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1973729de186450f78c099637e1fce743fe531862c52Andreas Huber
19745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
197597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
19765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
19775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
19795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
19805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
19825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
19865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
19875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
19885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
19895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
19905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
19915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
19935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
19945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2016229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2017229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
2018229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused &&
2019229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                isFlexibleColorFormat(
2020229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                        mOMX, mNode, format.eColorFormat, &flexibleEquivalent) &&
2021229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                colorFormat == flexibleEquivalent) {
2022229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2023229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2024229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2025229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2026229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2065f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
2066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
2076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2082e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2083e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2084e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2086e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
20872472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2088e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2089e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2090e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
209194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
209294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2093e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2094e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2098e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2099e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2100e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2101e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2102e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2103e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2106e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2107e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2109e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2110e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2113e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2115e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2116e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2117e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2118e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2119e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2120e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2121e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2122e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2123e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2124e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
212889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        const char *mime, const sp<AMessage> &msg) {
212989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
213089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
213189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
213289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
213389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
213489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
215089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
215189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
215289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
215389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
215489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat);
215589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
215689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
215789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
215889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            err = setSupportedOutputFormat();
215989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
216089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
216189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setSupportedOutputFormat();
216289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2258a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2259a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2260a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2261a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2262a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2332c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2333c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2334c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2335c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
233689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
233789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
233889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
233989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
234089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
23510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
23520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
23530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
23540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
23560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
23580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
23590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
23600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
23610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
23640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
23670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
23680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
23690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
23700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
23730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
23750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
23760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
23770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
23780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
23790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
23800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
23820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
23830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
23840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
23850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
23860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
239796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
239896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
239996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
240096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
240196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
240296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
240396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
240496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
240596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
241396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
241496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
247896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
249496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
249596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
255496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2563a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2564a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2565a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2566a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2567a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2568a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2569a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2570a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2571a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2572a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2573a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2574a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2575a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2576a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2577a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2578a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2579a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2580a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2581a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2582a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2583a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2584a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2585a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2586a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2587a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2588a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2589a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2590a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2591a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2592a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2593a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2594a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2595a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2596a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2597a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2598a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2599a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2600a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2601a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2602a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2603a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2604a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2605a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2606a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2607a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2608a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2609a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2610a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2611a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2612a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2613a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2614a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
262296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
262396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
26340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
26350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
26360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
26370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
26380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
26390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
26400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
26410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
26420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
26430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
26767c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
26777c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
26787c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
272096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2723c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2724c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2725c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2726c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2727c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2728c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2729c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2730c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2731c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2732c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2733c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2734c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2735c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2736c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2737c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2738c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2739c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2740c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2741c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2742c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2743c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2744c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2745c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2746c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2747c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2748c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2749c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2750c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2751c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2752c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2753c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2754c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2755c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2756c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2757c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2758c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2759c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2760c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2761c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2762c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2763c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2764c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2765c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2766c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2767c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2768c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2769c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2770c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2771c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2772c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2773c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2774c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2775c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2776c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2777c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2778c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
277989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
278089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
27814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
27824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
27834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
27844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
27854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
27864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
27874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
27884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
27894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
27904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
27914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
279289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
279389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
279489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
27954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
279689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
279789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
279889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
28004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
28014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
28024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
28034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
28044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
28064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
28074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
28094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
28104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
28114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
28124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
28134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
28144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
28154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
28164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
28174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
28184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
28194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
28204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
28214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
28234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
28254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
28264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
28274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
28284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
28294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
28304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
28324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
28334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
28344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
28364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
28374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
28384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
28394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
28404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
28414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
28424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
28444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
28454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
28464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
28484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
28494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
28504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
28514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
28524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
28534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
28544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
28554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
285689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
285789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
285889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
288596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
288696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
289996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2978d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2979d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2980d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2981d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2982d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2983d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2984d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2985d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2986d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2987d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2988d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2989d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2990d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2991d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
29927e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
29937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
29947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
29967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
29977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
29987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
29997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
30007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
30017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
30027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
30037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
30047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
30057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
30067e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
30077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
30087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
30097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
30107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3011e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
30127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3013c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3014c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3015c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3016c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
30177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
30187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
30197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3027609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3058229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
305903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
306003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
306103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
306203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
306303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
306403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
306503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
306603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
306703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
306803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
306903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
307003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
307103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
307203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
307303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) {
307403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3075229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
307603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
307703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3078b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3079b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3080b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3081b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3082b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3083b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3084b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3085b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3086b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3087b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3088b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3089b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3090b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3091b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
309203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
309303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
309403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
309503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
309603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
309703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
309803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
309903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
310003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
310103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
310203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    switch (fmt) {
310303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420Planar: // used for YV12
310403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
310503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
310603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
310703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
310803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
310903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
311003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
311103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
311203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
311303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
311403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
311503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
311603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
311703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
311803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
311903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
312003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
312103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
312203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
312303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
312403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
312503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
312603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
312703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
312803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
312903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
313003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
313103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
313203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
313303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
313403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
313503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
313603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
313703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
313803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3139229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3140229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3141229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3142229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3143229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3144229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3145229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3146229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3147229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3148229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3149229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3150229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3151229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3152229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3153229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3154229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3155229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3156229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3157229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3158229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3159229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3160229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3161229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3162229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
3163229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         uint32_t colorFormat, OMX_U32 *flexibleEquivalent) {
3164229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3165229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3166229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3167229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3168229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3169229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3170229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3171229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
3172229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3173229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3174229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3175229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3176229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3177229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3178229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3179229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3180229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3181229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3182229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3183229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3184229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3185229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3186229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3187229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3188229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3189229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3190229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3191229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3192229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3193229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3194229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3195229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3196229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3197229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3198229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3199229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
320003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
320103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3202e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3203e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
320431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
320531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3206e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
320731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
320831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
320931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
321031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
321131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3212e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3213e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
321431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
321531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
321631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
321731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
321831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3219e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3220e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3221e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3222e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3223e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3224e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3225e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3226e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3227e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3228e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
322903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    DescribeColorFormatParams describeParams;
323003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    InitOMXParams(&describeParams);
323103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.eColorFormat = videoDef->eColorFormat;
323203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameWidth = videoDef->nFrameWidth;
323303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nFrameHeight = videoDef->nFrameHeight;
323403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nStride = videoDef->nStride;
323503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    describeParams.nSliceHeight = videoDef->nSliceHeight;
323603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3237229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    if (describeColorFormat(mOMX, mNode, describeParams)) {
323803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                        notify->setBuffer(
323903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                "image-data",
324003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                ABuffer::CreateAsCopy(
324103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        &describeParams.sMediaImage,
324203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                                        sizeof(describeParams.sMediaImage)));
324303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
324403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
324591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
324691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
324791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
324891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
324991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3250e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3251e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
325291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3253e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3254e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
325591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
325691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
325791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
325891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3259e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3260e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3261e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3262e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3263e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3264e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
326531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3266e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3267e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3268e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3269e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3270e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3271e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3272e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3273e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3274577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3275577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3276577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3277e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3278e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3279e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3280e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3281e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
32824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
32844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
32854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
32864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
32874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
32884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
32894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
32904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
32914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
32934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
32944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
32954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
32964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
32974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
32984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
32994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
33004730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
33014730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
33024730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
33034730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33044730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
33054730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
33064730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
33074730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
33084730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33094730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
33104730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
33114730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
33124730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
33134730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33144730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
33154730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
33164730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
33174730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
33184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
33194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
33204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
33214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
33224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
33234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
33244730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
33254730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3326e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3327e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3328e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3329e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3330e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3331e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3332e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3333e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3334e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3335e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3336e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3337e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
333831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3339e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3340e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3341e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
334231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
334331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
334431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
334531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
334631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
334731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
334831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
334997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3350e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3351e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3352e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3353e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3354e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3355e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3356e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3357e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3358e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3359e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3360e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
336114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3362e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3363e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
336414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
336514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
336614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
336714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
336814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
336914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3370e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3371e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3372e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3373e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3374e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3375e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3376e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
33778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3378e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
33798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
33809806555d3930be43e11106281dee354820ac1c88Andreas Huber
3381e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3382e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3383e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3384e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3385e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3386e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3387e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3388e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3389e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3390e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3391e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3392e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3393e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3394e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3395e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3396e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3397e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3398e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3399e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3400e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3401e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3402e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
34039806555d3930be43e11106281dee354820ac1c88Andreas Huber
3404e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3405e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3406e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3407e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3408e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3409e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3410e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3411e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3413e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3414e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3417e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3419e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3420e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3421e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3422e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3423e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3424e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3425e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3426e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3427e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3428e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3429e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3430e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3431e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3441e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3442e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3443e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3444e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3445e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3446e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3447e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3448e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3449e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3450e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3451e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3452e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3453e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3454e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3455e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3456e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3457e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3458e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3459e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3460e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3461e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3462e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3463e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3464e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3465e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3466e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3467e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3468e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3469e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3470e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3471e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3472e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3473e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3474e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
347597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
347697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
347797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
347897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3479e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
348097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
348197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
348297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
348397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
348497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
348597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
348697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
348797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
348897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
348997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
349097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
349197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3492e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
34938c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
34948c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
34958c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
34968c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
34978c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
34988c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
34998c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
35008c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
35018c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
35028c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
35038c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
35048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
35058c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
35068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
35078c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
35088c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
35098c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
35108c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
351110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
351210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
351310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
351410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
351510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
351610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
351710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
351810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
351910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
352010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
352110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
352210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
352310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
352410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
352510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
352610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
352710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
352810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
352910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
353010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
353110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
353210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
353310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
353410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
353510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
353610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3538e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
354131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
354231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
354331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
354431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
354531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
354631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
354731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3548e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3549e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3550e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3551e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
35524e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
3553e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3554e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3555e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3556e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3557e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3558e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3559e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3560e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3561e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3562e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3563e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3564e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3565e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3566e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3567e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3568e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3569e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3570e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3571e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3572e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3573e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3574e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3575e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3576e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3577e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3578e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3579e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3580e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3581e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3582e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3583e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3584e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
358531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
358631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
358731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
358831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
358931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
35905778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3591cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3592d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3593251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3594251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3595251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3596251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3597251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3598251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3599251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3600251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3601251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3602251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3604251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3605cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3606cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3607cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3636bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3637bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3638bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3639bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3640bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
364187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
364287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
364387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
364487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
364587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
364687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3648bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3649bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3650bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3651bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3652bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3653bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3654bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3655bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3656bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3657bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3658bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3659bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3660bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3661bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3662bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3663bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3664bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3665bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
36781e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
36791e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
37071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
3715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
3718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
3721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
37221e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
3723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
3726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
3728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
3732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
3733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
3734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
3735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3741bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
3742bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
3743bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3745bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3748bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3749bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3750bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3751bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3752bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3755eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3756eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3757eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3758496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3759496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3760496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3761496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3762496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3763496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3764496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3765496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3766496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3767496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3768496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3769496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3770496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3771496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3772496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3773496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3774496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3775496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3776eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3777eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3778eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3779eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3780eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3781eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3782eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3783eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3784eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3785eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3786eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3787eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3788eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3789eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3790eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3791eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3792eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3793eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3794eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3795eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3796f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3801ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3802ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
38267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
38277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
3828251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
38297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
38307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
38317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
38327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
38337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3834ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3835ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3836251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
3837ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3838ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3839ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3840ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3841ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
384230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
384330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
384430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
384530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
384630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
384730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
384830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
384930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
385030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
385130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
385230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
385330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
385430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38665e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
38675e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
38685e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
38695e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
38705e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
38715e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
38725e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
38735e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3875609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
38870af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
38880af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
38890af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
38900af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
38910af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
38920af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
38930af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
38940af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
38950af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
38960af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3906609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3914609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3928784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
39403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3948251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
3949251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
3950251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
3951251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
3952251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
3953251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
3954251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
39603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3961349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3962349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
397096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
397196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
397296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
397396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
397496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
3975d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4005d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4006609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
40092d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
4012609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4023609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
40242d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
40265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4027a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
40285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40292d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4030a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40337fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
40347fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
40357fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
40367fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
40377fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
40387fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
40397fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
40407fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
40413831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
40422d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
40465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
40475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
40485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
40495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4060dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4061dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4062dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4063dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
40825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
40835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
40845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
4087d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4088d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4095078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
40963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
4097078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
40985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
40995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
41005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4101078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
4104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
41063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
4107078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4109078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4110349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4122054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4123054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4124054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4125054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4126054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4127e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4128054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4129054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4130054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
41435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
41445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
41495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
41505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4152dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
41533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4154dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4155dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4156dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
41573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4158dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4159dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
4162349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4163349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4176dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4180625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4181625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4182625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4183625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4220784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4221609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
42225778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4223349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4246054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4257a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4258a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4259609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
42605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4261349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
42625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
42635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
42645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
42675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
42685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
426931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4270577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
4271577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
4272577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
42734bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4274577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
42755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4277308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4278308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4279308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4280308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4281308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4282308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4283308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4284308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4285308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4286496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
428721ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4288496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4289496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4290496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
42915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
429221ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
42958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
42968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
42975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4300d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4301609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
43022d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
43035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4305609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
43105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
43145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
43155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4317d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4318dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4341609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4347577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4348577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4349577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4350577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4351577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4352577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4353577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
43566aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
435779ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
43586fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4361fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4362fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4363fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4364fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4365fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4366fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4367fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4368fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
436947aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4370fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4371fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4372fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4373fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4374fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
43755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4376fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4377fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4378fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4379fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4380fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
43815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
43831e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4384cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4385cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4386251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4387cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4388cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
43906fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
43916fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
43926fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
43936fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4423c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4424609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4425c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4426349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4427c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4428c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4430c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4431c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4449f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4455ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4456ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4457ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
4458ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4459ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4460ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4461ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4462ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4463ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4464ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4465ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4466308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4467ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4468c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
44835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
44845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
44855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
44865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
44875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
44885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4491c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4492c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
449454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
449554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4496c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4498d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4502c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4508d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4512c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
451630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
451730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
451830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
451930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
452030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
452130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4531c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4532c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4534c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
45355778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
45365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4537c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
45385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
45395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4540c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
45415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4547ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4548ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4549ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4550ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
4551ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4552ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4553ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4554ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4555ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4556e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
45575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4561d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
45627791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
45635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4564e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4565e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4566e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4567afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4568e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4569e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4570e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4571afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
45725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
45735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
45745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
45765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
45775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
45785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
45805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
45815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
45825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
45835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4584e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
45855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
45881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
45891065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
45901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
45911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4592e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4593e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4595078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
4596078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4597078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
45981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4599078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
46021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
46037a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
46047a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
46051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
46061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
46071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
46081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
46091065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4610c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
46115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
46127791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
46137791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
46145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
46157791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
46165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4617c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4618cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4620c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4622ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4626ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4627ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4628ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4629ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
46300167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4631ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4632ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4633afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
46385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4639d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
46405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
46415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
46425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4643c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4644c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4645c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4646c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
46475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
46485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4649c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4650c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4651c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4653c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4654c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4655c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4656c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4658f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4659f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4660f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4661f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4662f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4664054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4665a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4666e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4667e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
46684e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
4669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4670c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4671c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4672c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
467854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4679f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
4680f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
4681c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4689c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
469054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
469154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4692d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
469354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
469454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
469554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4696c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4697c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4698c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4699c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4700c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4701c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4706c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4708c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
47097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
47107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
47117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
47127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
47137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
47147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
47157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
4717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4718c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
4719c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4720c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4721c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
4724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4727c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4728c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
472954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
4730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
4731c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4732c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4733c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4734c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4735c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4736c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
4737c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4738c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4739d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4740c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
4741c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4742c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4744c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4745c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
4747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
4748c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4749c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
4751c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4752c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4753c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
47545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
47555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
47565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
47585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
47605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
47615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
47635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4765c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
4766c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
4767c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
4768251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4769c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
47705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
4773386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
47745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
47751173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
47761173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
47771173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
47781173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
47791ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
47801ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
47811ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
47821ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
47875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4788d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
4789e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4790e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
47915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
47925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4793c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4794c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
47955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
47965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4798ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
47997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
48007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
48017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
4802d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
48037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
48047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
48057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
48067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
48077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
48087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4809a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4810a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4811a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4812a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4813a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4814a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4815a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4816a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4817a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4818a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4819a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4820a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4821a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4822a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4823a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4824a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4825a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
48262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
482794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
482894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
482994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
483094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
483194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
483294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
483394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
483494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
483594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
483672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
483772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
48382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
48392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
48402c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
48412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
48422c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
48432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
48442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
48452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
48462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
48472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
48482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
48492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
48502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
48512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
48522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
48532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
48542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
48552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
48562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
48572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
48582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
485972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
486072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
486172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
486272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
486372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
486472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
486572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
486672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
486772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
486872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
486972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
487072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
487194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
487294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
487394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
487494ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
487594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
48767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
48777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
48787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
48797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
48807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
48817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
48827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
48837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
48847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
48857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
48867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
48877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
48887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
48897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4890c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
48915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
48925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
48945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4902f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
49073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4909cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4910cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
491129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4912cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4913cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4914cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
4915251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
491691bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
491791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4918cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4931f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
493372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
49416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
49426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
49436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
49446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
49456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
49466463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
49476463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
49486463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
49496463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
49506463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
49516463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
49526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
49536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
49546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
49556463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
4956d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
49576463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
49586463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
49596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
49606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4990f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
49953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
500072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5007d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5008d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5009d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5010d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5011d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5012d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5013d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5014d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5015d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5016d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5017d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5018d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5019d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5020d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5021d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5022d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
50236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
50246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
50256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
50266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
50276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
50286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5055f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5056349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5057349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5060f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5061ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5065054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5066054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5067054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5068054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5069054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5070054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5073054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5074054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5075054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
50764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
50774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
50784dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5079054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5080054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5081054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
5097349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5098349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5107c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5113f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5114349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
51153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5116349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5117349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5118349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5119349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5120349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51233cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
51253cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
51263cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
51273cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
51283cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
51293cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
51303cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5131349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5132349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5135f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
51363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5141f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5147c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5149c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5150c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
515254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5153c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5154c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5155349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5156349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
51697a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5170d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
5171d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5172d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5173d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5174d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5175d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5176d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5177349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5178349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5196496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5197496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5198496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5199496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5200496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5201496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5202496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5203496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5204496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5205496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5206496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5207a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5208a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5209a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5210a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5211a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5212a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5213a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5214a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5215a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5216a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5217a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5218a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5219a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5220a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5221a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5222a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5223a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
52247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
52257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
52266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
52277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
52287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
52297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
52307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
52314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
52324dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
52334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
52344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
52354dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
52364dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
52374dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
52384dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
52394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
52404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
52414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
52424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
52434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5252a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5253a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5254530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5255a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5256a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5257a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5258a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5259a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5260a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5261a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5262a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5263a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5264a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5265a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5266a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5267a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5268a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5269a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5270a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5271a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5272a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5273a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
527472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
527572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
527672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
527772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
527872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
527972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
528072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
528172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
528272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
528372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
528472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
528572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
528672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
528772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
528872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
528972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5290e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5291e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5292e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5293e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5294b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5295b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5296e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5297e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5298e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5299e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5300b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5301b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5302b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5303b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5304b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5305b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5306b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5307b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5308b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5309b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5310b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5311b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5312b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5313b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5314b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5315b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5316e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5317e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5318a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5319a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5320a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
53216507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
53226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5323d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
53246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
53256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
53266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
53276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
53286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
53296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
53306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
53316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
533931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5340054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5346349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
534931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
535031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
53523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5371f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5376f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5394349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5396349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
53973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5398349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5399349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
54143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5436cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5437cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5438cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
543929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5440cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5441cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5442cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5443251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5444d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5445755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5446755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5447755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5448755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5449755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5450755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5451755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5452755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5453cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
545931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
546031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
54613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5464349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5465349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5466349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5467349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5483f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
54845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
54855778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
55173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
551831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
55195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
552031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
55325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5538349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5539349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5540349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5541349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5542349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5543349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5544349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
55490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
55515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55590167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
55600167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5561bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5562bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5563bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5564bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5565bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5566bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5567bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5588f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5592f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5620f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
56213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5644f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
56493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5679f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
56817a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5682d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5683d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5692e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5693e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5694e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5695e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5696e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5708349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5709349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5710349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5711349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5712609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5713349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5714349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5715349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5716349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
57173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5718349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5719349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5720349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5721349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5722349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5723349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5724349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5732f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
5733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5738f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
5739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5744f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
5745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
57487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
57497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
57507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
57517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5753d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5759dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
5760dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
5761f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
5762f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
5763f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
5764f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
5770