ACodec.cpp revision 37b2b389139ed638831e49708c947863eef631ef
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),
42237b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
4232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
424609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
425ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
426ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
428c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
441dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
446f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
449f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
460a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
462a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
463a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
464a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4655778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4715778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4855778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
489f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4907a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
494f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
501c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
50230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
50330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
50430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, id()))->post(3000000);
50530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
509496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
510496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
511496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
5214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
532054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
533054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
534054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
535054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
536054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
546609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
559ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
561afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
562afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
563afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
564afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
566308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
567308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
569ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
570ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
571ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
572ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
573ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
574ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
575308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
576308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
577308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
578308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
579ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
581ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
583ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
584ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
585ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
586ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
587ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5891065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5921065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
600d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
603eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
604eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
605eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
6065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
607eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
609eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
612eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
620054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
644e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
645e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
646e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
647e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
648e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
649e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
650e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
651e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
652e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
653e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
654e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
655e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
659e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
660e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
661e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
662e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
663e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
664e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6673c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6683c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6695ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6703c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6713c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6723c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6735a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    int omxUsage = usage;
6743c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
6751713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang    if (mFlags & kFlagIsGrallocUsageProtected) {
676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
6985a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    int consumerUsage = 0;
6995a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    err = mNativeWindow->query(
7005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            mNativeWindow.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS,
7015a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            &consumerUsage);
7025a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    if (err != 0) {
7035a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        ALOGW("failed to get consumer usage bits. ignoring");
7045a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        err = 0;
7055a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    }
7065a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
7075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec) + %#x(Consumer) = %#x",
7085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            omxUsage, usage, consumerUsage, usage | consumerUsage);
7095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    usage |= consumerUsage;
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
7123c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
71529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
719ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
720ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
721ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
722ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
723ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
724ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
725ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
726ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
727ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
728ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
729ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
730ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
731ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
732ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
733ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
735258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
736258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
738258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
739258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
74029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
741258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
742258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
743258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
744258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
745e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
746e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7471faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7481faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
749e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
750e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
751e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
752e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
753e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
754e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
755e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7561faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7571faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
758e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
759e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
760258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
761258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
762258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
763258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
764e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
765e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
766e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
767e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
768e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
769609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
770e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
771e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
772e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
773258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
774258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
775258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
776258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
78129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
797e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
799609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
8058ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
8061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
80829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
81374006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
81474006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
81674006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
81774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
81874006804065941841883c4b46ee785070164023fJamie Gennis
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
823609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
82474006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
82974006804065941841883c4b46ee785070164023fJamie Gennis
830609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
84274006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8513fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8523fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8533fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8543fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
866e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
868609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
874054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
875054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
878054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
892609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
900054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
902054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
903054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
904054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
907054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
908054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
909609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
910054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
911054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
913054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
914054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
915054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
916054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
917054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
918054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
919054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
923609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
9271e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9293fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
9303fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9343fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
937f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9388ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
940ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
941ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
942ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
943ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
944ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
945ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
946ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
9471e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
94829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
949c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
950c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
952054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
958054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
966054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
968054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
971054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
972054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
975054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
976054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
978054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
979054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
982054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
983d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
984d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
985d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
986054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
987d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
988d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
989d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
990d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
991d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
992d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
993054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
994054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
995d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
996d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
997054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
998054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10212ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
10222ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
10232ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
10242ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
10403fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1052f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
10822944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
10832944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
10842944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
10852944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1092729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1093729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1094bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1095bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1096c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1097c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1098c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1099c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
11022472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
11032472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
110894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
110994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
111094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
111194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1112ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1113ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
11142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
11152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1116ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1117ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1118774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1119774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
112097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
112197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
11228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
11238a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11585ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
11764e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1177e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1200308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1201308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1203308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1204308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1205308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1207308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
12083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
12093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
12103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
12113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
12123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
12133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
12143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
12153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
12163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
12183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
12193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
12203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
12213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
12233a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
12243a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12253a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12263a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
12273a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
12283a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
12293a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
12313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
12333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1234308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1235308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1236308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1237308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1238308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1239308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1240308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1241308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1242308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1243308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1244308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1245308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1246308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1247308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1248308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1249308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1250308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1251308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1252a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1253a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1254a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1255a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1256a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1257a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
125894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
125994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
126337b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
126437b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
126537b2b389139ed638831e49708c947863eef631efRonghua Wu        }
126637b2b389139ed638831e49708c947863eef631efRonghua Wu
12672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
126994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
127072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
127172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
127272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
127372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
127472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
127572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1276308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1277308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
12783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1279054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
12800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
12813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1282054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1283e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1284e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
12851713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
12861713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
12871713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
12881713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
12891713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
12901713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
12911713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
12921713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
12931713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12941713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1295e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
12963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
12975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<NativeWindowWrapper> windowWrapper(
12985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                static_cast<NativeWindowWrapper *>(obj.get()));
12995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
13005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13016597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
13026597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
13036597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
13046597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
13056597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
13066597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
13076597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
13086597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
13096597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
13106597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
13116597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
13126597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
13136597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
13146597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
13156597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
13166597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
13176597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
13186597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
13195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
13205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
13215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
13225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1323ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
13245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
132597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
132697827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
13275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
13285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
13305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
133197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
13325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
13335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1334fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1335fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1336d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1337d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1338d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1339d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1340d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1341d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1342d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1343d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1344d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
13453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
13463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1347d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1348d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1349d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1350d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1351d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1352d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
13535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1354ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1355ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1356ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
13573fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
13583fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
13593fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
13603fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
13613fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
13623fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
13633fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
13643fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
13653fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
13665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
13675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
13685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
13695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
13705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1371fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1372e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
13745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
13755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
13765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
13785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
13795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
13805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
13815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
13825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
13845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
13855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
13865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
13875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
13885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
13895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
13905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
13915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
13925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
13935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
13945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
13965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
13975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
13985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
13995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
14005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
14015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
14035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
14045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
14055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
14065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
14075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
14085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
14105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
14115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
14125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
14135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1414e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
14155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
14165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
14175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
14185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
14195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
14205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
14215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1422fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
14230167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
14245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
14255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
14265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
14275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
14285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
14290167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1430e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1431e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1432e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1433e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1434e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1435e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1436e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1437054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1438054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1439308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
14403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
14413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
14423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
14433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
14443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
14453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14523a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14533a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
14543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
14553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14563a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14573a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
14583a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            sp<NativeWindowWrapper> nativeWindow(
14593a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
14603a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            CHECK(nativeWindow != NULL);
14613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            mNativeWindow = nativeWindow->getNativeWindow();
14623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            native_window_set_scaling_mode(
14643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
14653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
14683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
14693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        CHECK_EQ((status_t)OK, initNativeWindow());
14703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
14723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
14733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
14743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
14753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
14763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
14773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
14783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
14793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK(outputFormat->findInt32("color-format", &colorFormat));
14803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
14813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
14823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
14833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
14843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
14853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
14863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
14873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
14883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
14893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
14903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
14913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
14923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
14933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
14943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
14953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
14963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
14973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
14983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
14993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
15003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
15023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
15033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
15043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
15053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
15063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
15083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
15093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
15123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
15133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
151442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
151542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
151642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
151742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
151842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
151942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
152042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
152142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
152242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
152342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
152442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
152542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
152642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1533aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1534b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
15358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
15362965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
15378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1538ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1539ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1540ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1541aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1542aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1543aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1544b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1545b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1546b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1547ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
15488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
15498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
15508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15512965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
15522965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
15532965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
15542965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
15558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
15568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
15588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
15608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
15628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
15648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
15668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
15688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
15708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
15728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
15748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1576ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
15774471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
15782965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
15792965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1581729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1583729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1585729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1587729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1588729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1589729de186450f78c099637e1fce743fe531862c52Andreas Huber
1590729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
15972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
15982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
15992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
16002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
16012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
16022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
16032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
16042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1605516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1606cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1607cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1608516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1609cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
16102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1611516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1612516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1613516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
16142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
16152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1616516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1617516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1618516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
16192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
16202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
16212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1622516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1623516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
16242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1625ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1626ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1627ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1628ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1629ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1630ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1631ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1632ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1633ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
163497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
163597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
163697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
163797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
163897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
163997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
164097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
164197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
164297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
16438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
16448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
16458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
16468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
16478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
16488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
16498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
16508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
16518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber
16544471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
16554471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
16564471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
16574471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
16588b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
16598b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
16608b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
16619806555d3930be43e11106281dee354820ac1c88Andreas Huber
16628b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
16638b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
16648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
16658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
16669806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
16679806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
16689806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
16699806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
16709806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
16719806555d3930be43e11106281dee354820ac1c88Andreas Huber
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16794e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
16804e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1681e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1682e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1683e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1684e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1685e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1753aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
17548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
17552965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
17562965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1757ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1758ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1759ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1760ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1821aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1823b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1824b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1825b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1826b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1827b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1828b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1829b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1830b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1831b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1832b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1833b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1834b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1835b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1836b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1837b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1838b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1839b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1840b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1841b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1842b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1843b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1844b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1845b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1846b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1847b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1848b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1873ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1874ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1875ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1876ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1877ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
18808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
18818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
18828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
18838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
18848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
18858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
18862965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
18878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
18888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
18898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
18908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
18918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
18928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
18938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
18948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
18958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
18968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
190097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
190197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
190297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
190397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
190497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
190597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
190697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
190797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
190897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
190997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
191097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
191197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
191297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
191397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
191497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
191597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
191697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
191797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
191897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
191997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
192097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
192197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
192297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
192397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
192497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
192597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
192697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
192797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
192897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
192997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
193097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
193197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
193297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
193397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
193497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
193597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
193697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
19378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
19388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
19398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
19408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
19418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
19438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
19448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
19458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
19478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
19488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
19498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
19508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
19528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
19538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
19548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
19568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
19578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
19588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
19598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
19608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
19628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
19638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
19648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
19668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
19678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
19698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
19708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
19718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
19728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
19738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
19748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2021729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2022729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2024729de186450f78c099637e1fce743fe531862c52Andreas Huber
2025729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2026729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2027729de186450f78c099637e1fce743fe531862c52Andreas Huber
2028729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2029729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2030729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2031729de186450f78c099637e1fce743fe531862c52Andreas Huber
2032729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2037729de186450f78c099637e1fce743fe531862c52Andreas Huber
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2041729de186450f78c099637e1fce743fe531862c52Andreas Huber
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2046729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2047729de186450f78c099637e1fce743fe531862c52Andreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2051729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
2052729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
2053729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2054729de186450f78c099637e1fce743fe531862c52Andreas Huber
20552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
20562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
20572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
20582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
20592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
20602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
20612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
20622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
20632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
20642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
20652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
20662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
20672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
20682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
20692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
20702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
20712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
20722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
20732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
20742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
20752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
20762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
20772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
20782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
20792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
20802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
20812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
20822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2083729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2084729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2085729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2086729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2087729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2088729de186450f78c099637e1fce743fe531862c52Andreas Huber
2089729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2090729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2091729de186450f78c099637e1fce743fe531862c52Andreas Huber
2092729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2093729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2094729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2095729de186450f78c099637e1fce743fe531862c52Andreas Huber
2096729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2097729de186450f78c099637e1fce743fe531862c52Andreas Huber
2098729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2099729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2100729de186450f78c099637e1fce743fe531862c52Andreas Huber
2101729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2102729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2103729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2104729de186450f78c099637e1fce743fe531862c52Andreas Huber
2105729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2106729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2107729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2108729de186450f78c099637e1fce743fe531862c52Andreas Huber
2109729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2110729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2111729de186450f78c099637e1fce743fe531862c52Andreas Huber
2112729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2113729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2114729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2115729de186450f78c099637e1fce743fe531862c52Andreas Huber
2116729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2117729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2118729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2119729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2120729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2121729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2122729de186450f78c099637e1fce743fe531862c52Andreas Huber
2123c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2124c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2125729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2126729de186450f78c099637e1fce743fe531862c52Andreas Huber
2127729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2128729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2129729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2130729de186450f78c099637e1fce743fe531862c52Andreas Huber
21315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
213297827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
21335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
21345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
21355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
21365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
21375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
21385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
21395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
21405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
21415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
21425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
21435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
21445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
21455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
21465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
21475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
21485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
21495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
21505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
21515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2152f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
21550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
21560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2174229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2175229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
21760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
21770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
21780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
21790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2180229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2181229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2182229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2183229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2184229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
22240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
22250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
22260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
22270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
22280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
22290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
22300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
22310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
22320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
22330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
22340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
22350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
22360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
22370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
22380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
22430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
22440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
22470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
22480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
22490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
22500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
22510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
22520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
22530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
22540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
22550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
22560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
22570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
22580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
22600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
22610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
22630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
22640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
22660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
22670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
22680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
22690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
22700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
22710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
22720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
22740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
22750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
22760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
22770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
22780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
22790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
22800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
22810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2288e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2289e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2290e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2291e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2292e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
22932472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2294e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2295e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2296e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
229794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
229894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2299e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2300e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2303e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2304e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2305e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2306e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2307e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2308e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2309e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2312e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2313e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2314e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2315e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2316e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2317e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2318e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2319e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2322e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2323e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2324e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2325e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2326e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2327e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2328e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2329e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2330e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
23340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
233589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
233689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
233789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
233889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
233989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
234089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
235689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
235789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
235889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
235989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
23600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
236189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
236289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
236389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
23640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
236589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
236689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
23670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
236889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
237478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
237578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
237678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
237778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
237878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
237978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
238078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
238178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
238278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
238478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2473a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2474a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2475a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2476a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2477a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2547c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2548c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2549c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2550c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
255189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
255289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
255389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
255489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
255589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
25660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
25670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
25680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
25690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
25710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
25730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
25740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
25750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
25760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
25770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
25780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
25790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
25800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
25820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
25830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
25840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
25850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
25860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
25870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
25880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
25900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
25910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
25920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
25930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
25940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
25950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
25970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
25980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
25990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
26000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
26010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
261296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
261396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
261496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
261596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
261696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
261796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
261896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
261996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
262096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
262896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
262996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
269396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
270996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
271096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
276996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2778a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2779a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2780a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2781a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2782a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2783a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2784a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2785a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2786a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2787a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2788a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2789a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2790a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2791a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2792a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2793a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2794a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2795a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2796a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2797a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2798a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2799a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2800a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2801a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2802a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2803a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2804a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2805a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2806a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2807a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2808a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2809a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2810a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2811a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2812a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2813a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2814a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2815a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2816a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2817a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2818a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2819a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2820a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2821a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2822a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2823a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2824a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2825a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2826a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2827a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2828a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2829a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
283796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
283896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
28490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
28500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
28510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
28520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
28530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
28540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
28550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
28560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
28580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
28917c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
28927c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
28937c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
293596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2938c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2939c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2940c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2941c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2942c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2943c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2944c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2945c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2946c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2947c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2948c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2949c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2950c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2951c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2952c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2953c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2954c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2955c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2956c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2957c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2958c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2959c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2960c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2961c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2962c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2963c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2964c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2965c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2966c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2967c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2968c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2969c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2970c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2971c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2972c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2973c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2974c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2975c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2976c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2977c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2978c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2979c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2980c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2981c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2982c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2983c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2984c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2985c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2986c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2987c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2988c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2989c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2990c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2991c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2992c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2993c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
299489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
299589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
29964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
29974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
29984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
29994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
30004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
30014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
30024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
30034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
30044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
30054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
30064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
300789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
300889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
300989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
30104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
301189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
301289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
301389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
30144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
30154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
30164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
30174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
30184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
30194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
30214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
30224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
30234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
30244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
30254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
30264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
30274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
30284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
30294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
30304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
30314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
30324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
30334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
30344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
30354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
30364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
30384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
30394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
30404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
30414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
30424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
30434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
30444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
30454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
30464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
30474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
30484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
30494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
30514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
30524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
30534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
30544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
30554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
30564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
30574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
30594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
30604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
30614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
30634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
30644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
30654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
30664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
30674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
30684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
30704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
307189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
307289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
307389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
30745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
30755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
30765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
30775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
30785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
30825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
30835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
30855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
30895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
30925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
30935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
30955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
30965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
310096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
310196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
31025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
31035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
31045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
31055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
311496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
31205778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31225778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
31235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
31375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
314878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
314978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
317778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
317878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
317978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3197d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3198d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3199d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3200d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3201d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3202d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3203d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3204d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3205d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3206d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3207d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3208d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3209d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3210d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
32117e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
32127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
32137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
32147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
32157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
32167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
32177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
32187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
32197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
32207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
32217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
32227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
32237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
32247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
32257e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
32267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
32277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
32287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
32297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3230e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
32317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3232c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3233c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3234c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3235c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
32367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
32377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
32387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3246609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3276229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
327703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
327803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
327903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
328003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
328103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
328203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
328303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
328403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
328503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
328603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
328703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
328803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
328903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
329003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
32915a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
32925a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
329303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3294229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
329503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
329603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3297b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3298b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3299b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3300b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3301b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3302b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3303b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3304b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3305b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3306b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3307b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3308b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3309b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3310b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
331103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
331203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
331303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
331403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
331503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
331603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
331703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
331803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
331903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
332003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
33215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
33225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
33235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
33245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
33255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
33265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
33275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
33285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
33295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
33305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
33315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
33325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
33335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
33345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
33355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
33365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
33375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
33385a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
33395a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
33405a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
33415a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
33425a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
33435a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
33445a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
33455a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
334603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
334703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
334803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
334903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
335003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
335103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
335203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
335303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
335403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
335503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
335603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
335703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
335803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
335903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
336003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
336103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
336203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
336303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
336403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
336503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
336603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
336703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
336803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
336903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
337003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
337103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
337203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
337303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
337403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
337503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
337603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
337703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
337803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
337903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
338003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3381229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3382229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3383229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3384229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3385229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3386229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3387229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3388229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3389229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3390229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3391229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3392229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3393229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3394229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3395229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3396229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3397229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3398229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3399229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3400229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3401229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3402229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3403229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3404229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
34050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3406229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3407229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3408229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3409229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3410229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3411229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3412229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3413229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
34140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3415229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3416229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3417229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3418229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3419229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3420229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3421229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3422229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3423229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3424229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3425229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3426229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3427229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3428229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3429229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3430229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3431229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3432229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3433229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3434229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3435229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3436229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3437229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3438229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3439229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3440229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3441229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3442229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
344303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
344403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3445e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3446e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
344731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
344831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3449e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
345031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
345131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
345231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
345331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
345431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3455e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3456e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
345731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
345831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
345931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
346031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
346131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3462e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3463e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3464e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3465e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3466e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3467e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3468e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3469e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3470e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3471e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
34720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
34730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
34740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
34750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
34760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
34770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
34780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
34790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
34800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
34810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
34820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
34830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
34840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
34850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
34860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
34870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
34885a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34895a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
34905a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
34915a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
34925a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
34935a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
34945a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
34950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
349603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
349703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
349891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
349991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
350091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
350191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
350291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3503e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3504e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
350591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3506e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3507e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
350891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
350991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
351091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
351191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3512e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3513e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3514e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3515e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3516e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3517e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
351831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3519e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3520e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3521e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3522e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3523e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3524e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3526e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3527577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3528577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3529577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3530e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3531e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3532e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3533e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3534e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
35354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
35364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
35374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
35384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
35394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
35404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
35414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
35424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
35434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
35444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
35454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
35464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
35474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
35484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
35494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
35504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
35514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
35524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
35534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
35544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
35554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
35564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
35574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
35584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
35594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
35604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
35614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
35624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
35634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
35644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
35654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
35664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
35674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
35684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
35694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
35704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
35714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
35724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
35734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
35744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
35754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
35764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
35774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
35784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3579e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3580e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3581e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3582e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3583e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3584e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3585e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3586e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3587e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3588e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3589e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
359131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3592e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3593e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
35945a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
35955a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
35965a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
35975a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
359831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
359931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
360031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
360131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
360231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
360331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
360431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
360597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3610e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
361714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
362014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
362114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
362214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
362314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
362414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
362514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
36338b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
36358b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
36369806555d3930be43e11106281dee354820ac1c88Andreas Huber
3637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3641e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3658e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
36599806555d3930be43e11106281dee354820ac1c88Andreas Huber
3660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3674e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3675e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3684e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3686e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3697e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3698e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3699e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3700e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3702e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3703e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3704e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3705e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3706e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3707e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3708e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3709e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3710e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3711e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3712e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3713e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3714e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3715e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3716e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3717e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3718e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3719e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3720e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3721e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3722e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3723e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3726e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3727e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3728e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3729e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3730e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
373197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
373297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
373397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
373497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3735e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
373697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
373797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
373897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
373997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
374097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
374197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
374297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
374397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
374497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
374597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
374697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
374797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3748e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
37498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
37508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
37518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
37528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
37538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
37548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
37558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    CHECK_EQ((status_t)OK, mOMX->getParameter(
37568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            mNode,
37578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
37588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            &params,
37598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            sizeof(params)));
37608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
37618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
37628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
37638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
37648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
37658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
37668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
37678c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
37688c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
37698c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
37708c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
37718c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
37728c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
37738c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
37748c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
37758c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
37768c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
37778c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
37788c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
37798c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
37808c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
37818c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
37828c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
37838c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
37848c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
378510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
378610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
378710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
378810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
378910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
379010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
379110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
379210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
379310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
379410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
379510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
379610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
379710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
379810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
379910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
380010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
380110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
380210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
380310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
380410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
380510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
380610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
380710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
380810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
380910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
381041d3f579d2c166984958263533284209b90c87d5Marco Nelissen
381141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
381241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
381341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    OMX_AUDIO_PARAM_MP3TYPE params;
381441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
381541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
381641d3f579d2c166984958263533284209b90c87d5Marco Nelissen
381741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    CHECK_EQ(mOMX->getParameter(
381841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                mNode, OMX_IndexParamAudioPcm,
381941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                &params, sizeof(params)),
382041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                             (status_t)OK);
382141d3f579d2c166984958263533284209b90c87d5Marco Nelissen
382241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
382341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
382441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("sample-rate", params.nSampleRate);
382541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
382610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
382710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3829e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
383231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
383331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
383431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
383531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
383631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
383731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
383831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3839e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3840e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
38434e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
3844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3850e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3851e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3852e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3853e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3854e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3855e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3856e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3864e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3865e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3866e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3869e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3870e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3871e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3872e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3873e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3874e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3875e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
387631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
387731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
387831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
387931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
388031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
38815778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3882cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3883d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3884251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3885251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3886251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3887251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3888251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3889251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3890251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3891251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3892251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3893251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3895251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3896cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3897cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3898cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3899bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3900bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3901bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3902bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3903bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3904bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3905bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3906bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3907bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3908bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3909bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3910bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3911bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3912bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3913bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3914bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3915bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3916bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3917bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3918bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3919bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3920bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3921bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3922bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3923bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3924bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3925bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3926bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3927bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3928bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3929bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3930bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3931bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
393287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
393387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
393487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
393587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
393687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
393787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3938bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3939bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3940bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3941bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3942bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3943bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3944bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3945bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3946bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3947bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3948bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3949bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3950bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3951bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3952bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3953bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3954bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3955bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3956bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3957bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3958bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3959bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3960bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3961bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3962bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3963bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3964bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3965bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3966bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3967bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3968bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
39691e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3970bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3971bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3972bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3973bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3974bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3975bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3976bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3977bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3978bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3979bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3980bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3981bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3982bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3983bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3984bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3985bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3986bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3987bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3988bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3989bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3990bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3991bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3992bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3993bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3994bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3995bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3996bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
39971e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3998bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3999bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
4000bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4001bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4002bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4003bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4004bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
4005bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4006bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4007bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
4008bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4009bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4010bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
4011bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
40121e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
4013bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4014bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4015bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
4016bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4017bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
4018bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4019bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4020bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4021bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
4022bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
4023bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
4024bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4025bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4026bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
4027bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4028bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4029bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4030bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4031bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
4032bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4033bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4034bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
4035bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4036bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4037bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4038bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4039bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
4040bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4041bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
4042bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4045eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4046eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4047eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4048496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4049496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4050496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4051496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4052496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4053496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4054496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4055496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4056496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4057496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4058496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4059496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4060496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4061496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4062496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4063496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4064496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4065496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4066eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4067eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4068eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4069eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4070eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4071eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4072eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4073eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4074eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4075eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4076eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4077eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4078eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4079eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4080eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4081eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4082eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4083eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4084eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4085eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4086f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4091ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4092ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
41167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
41177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
41197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
41207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
41217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
41227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
41237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4124ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4125ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4127ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4128ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4129ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4130ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4131ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
413230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
413330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
413430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
413530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
413630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
413730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
413830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
413930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
414030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
414130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
414230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
414330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
414430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41565e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
41575e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
41585e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
41595e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
41605e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
41615e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
41625e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
41635e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4165609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41760af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
41770af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
41780af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
41790af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
41800af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
41810af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
41820af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
41830af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
41840af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
41850af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
41860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4196609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4204609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4218784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
42303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
423629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4238251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4239251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4240251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4241251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4242251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4243251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4244251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
42503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
4251349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4252349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
425996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
426096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
426196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
426296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
426396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
426496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4265d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4295d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4296609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
42992d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
4302609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4313609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
43142d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
43165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4317a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
43185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43192d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4320a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
43247fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
43257fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
43267fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
43277fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
43287fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
43297fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
43307fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
43313831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
43322d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
43365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
43375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
43385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
43395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
43495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4350dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4351dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4352dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4353dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
43605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
43725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
43735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
43745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
4377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4385078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
43863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
4387078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
43885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
43895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
43905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4391078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4392d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4393d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
4394d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4395d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
43963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
4397078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4398d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4399078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4400349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4407d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4408054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4409054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4410054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4411054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4412054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4413054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4414054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4415054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4416054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4417e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4419054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4420054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
44335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
44345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
44355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
44365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
44375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
44395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
44405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4442dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
44433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4444dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4445dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4446dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
44473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4448dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4449dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
4452349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4453349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4466dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4470625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4471625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4472625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4473625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4510784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4511609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
45125778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4513349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4536054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4547a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4548a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4549609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
45505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4551349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
45525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
45535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
45545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
45575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
45585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
455931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4560577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
4561577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
4562577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
45634bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4564577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
45655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4567308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4568308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4569308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4570308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4571308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4572308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4573308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4574308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4575308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4576496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
457721ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4578496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4579496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4580496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
45815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
458221ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
45858b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
45868b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
45875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4590d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4591609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
45922d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
45935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4595609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
46005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
46045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
46055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4607d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4608dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4631609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4637577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4638577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4639577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4640577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4641577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4642577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4643577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
46466aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
464779ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
46486fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4651fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4652fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4653fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4654fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4655fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4656fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4657fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4658fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
465947aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4660fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4661fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4662fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4663fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4664fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
46655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4666fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4667fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4668fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4669fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4670fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
46715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
46731e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4674cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4675cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4676251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4677cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4678cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
46806fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
46816fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
46826fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
46836fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4713c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4714609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4715c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4716349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4717c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4718c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4720c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4721c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4739f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4744c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4745ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4746ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4747f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4748ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4749ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4750ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4751ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4752ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4753ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4754ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4755ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4756308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4757ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4758c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4759c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
47735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
47745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
47755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
47765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
47775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
47785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4783c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
478454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
478554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4788d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4792c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4798d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4802c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
480530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
480630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
480730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
480830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
480930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
481030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
481130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4821c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4823c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4824c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
48255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
48265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4827c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
48285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
48295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
48315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4837ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4838ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4839ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4840f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
4841ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4842ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4843ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4844ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4845ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4846e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
48475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4851d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
48527791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
48535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4854e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4855e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4856e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4857afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4858e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4859e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4860e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4861afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
48625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
48635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
48645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
48665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
48675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
48685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
48705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
48715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
48725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
48735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4874e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
48755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
48761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
48771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
48781065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
48791065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
48801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
48811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4882e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4883e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4885da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
4886078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4887078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
48881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4889078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
48921065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
48937a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
48947a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
48951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
48961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
48971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
48981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
48991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4900c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
49015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
49027791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
49037791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
49045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
49057791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
49065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4907c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4908cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4909c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4910c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4912ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4916ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4917ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4918ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4919ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
49201713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
49210167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4922ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4923ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4924afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
49295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4930d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
49315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
49325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
49335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4934c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4935c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4936c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4937c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
49385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
49395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4940c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4941c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4942c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4943c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4944c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4945c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4946c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4947c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4948c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4949f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4950f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4951f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4952f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4953f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4955054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4956a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4957e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4958e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
49594e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
4960054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4961c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4962c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4963c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4964c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4965c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4966c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4967c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4968c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
496954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4970f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
4971f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
4972c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4973c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4974c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4975c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4976c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4977c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4978c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4979c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4980c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
498154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
498254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4983d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
498454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
498554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
498654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4987c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4988c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4989c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4990c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4991c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4992c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4993c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4994c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4995c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4996c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4997c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4998c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4999c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
50007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
50017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
50027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
50037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
50047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
50057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
50067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5007c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5008c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5009c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5010c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5011c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5012c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5013c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5014c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5015c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5016c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5017c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5018c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5019c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
502054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5021c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5022c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5023c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5024c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5025c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5026c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5028c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5029c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5030d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5031c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5032c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5033c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5034c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5035c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5036c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5038c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5040c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5041c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5042c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5043c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5044c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
50455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
50465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
50475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
50495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
50515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
50525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
50545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5056c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5057c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5058c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5059251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5060c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
50615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
50645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5065d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5066e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5067e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
50685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
50695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5070c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5071c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
50725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
50735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
5075ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
50767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
50777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
50787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
5079d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
50807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
50817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
50827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
50837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
50847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
50857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
5086a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5087a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
5088a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5089a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5090a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5091a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5092a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5093a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5094a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5095a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5096a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5097a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5098a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5099a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5100a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5101a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5102a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
51032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
510494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
510594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
510694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
510794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
510894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
510994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
511094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
511194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
511294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
511372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
511472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
51152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
51162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
51172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
511837b2b389139ed638831e49708c947863eef631efRonghua Wu    if (err == OK && mCodec->mMaxFps > 0) {
511937b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
512037b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
512137b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
512237b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
512337b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
512437b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
512537b2b389139ed638831e49708c947863eef631efRonghua Wu
512637b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
512737b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
512837b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
512937b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
513037b2b389139ed638831e49708c947863eef631efRonghua Wu        }
513137b2b389139ed638831e49708c947863eef631efRonghua Wu    }
513237b2b389139ed638831e49708c947863eef631efRonghua Wu
51332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
51342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
51352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
51362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
51372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
51382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
51392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
51402c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
51412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
51422c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
51432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
51442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
51452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
51462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
51472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
51482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
51492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
51502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
515172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
515272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
515372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
515472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
515572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
515672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
515772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
515872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
515972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
516072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
516172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
516272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
516394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
516494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
516594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
516694ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
516794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
51687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
51697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
51707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
51717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
51727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
51737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
51747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
51757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
51767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
51777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
51787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
51797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
51807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
51817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
51835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
51845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
51865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
5188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5194f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
51993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5201cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5202cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
520329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5204cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5205cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5206cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5207251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
520891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
520991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5210cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5213f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5223f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
522572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
52336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
52346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
52356507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
52366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
52376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
52386463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
52396463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
52406463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
52416463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
52426463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
52436463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
52446463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
52456463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
52466463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
52476463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5248d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
52496463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
52506463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
52516463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
52526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5258f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
5271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5282f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5286f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
52873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5290f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
529272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5299d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5300d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5301d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5302d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5303d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5304d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5305d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5306d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5307d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5308d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5309d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5310d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5311d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5312d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5313d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5314d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
53156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
53166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
53176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
53186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
53196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
53206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5347f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5348349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5349349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5352f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5353ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5357054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5358054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5359054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5360054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5361054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5362054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5363054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5364054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5365054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5366054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5367054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
53684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
53694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
53704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
5389349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5390349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5398054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5399c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5400054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5401054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5402054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5403054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5404054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5406349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
54073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5408349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5409349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5410349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5411349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5412349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54153cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
54173cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
54183cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
54193cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
54203cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
54213cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
54223cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5423349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5424349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
54283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5441c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5443c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
544454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5447349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5448349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
54617a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5462d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
5463d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5464d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5465d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5466d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5467d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5468d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5469349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5470349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5488496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5489496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5490496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5491496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5492496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5493496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5494496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5495496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5496496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5497496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5498496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5499a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5500a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5501a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5502a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5503a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5504a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5505a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5506a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5507a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5508a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5509a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5510a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5511a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5512a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5513a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5514a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5515a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
55167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
55177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
55186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
55197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
55207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
55217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
55227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
55234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
55244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
55254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
55264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
55274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
55284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
55294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
55304dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
55314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
55324dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
55334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
55344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
55354dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5544a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5545a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5546530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5547a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5548a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5549a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5550a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5551a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5552a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5553a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5554a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5555a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5556a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5557a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5558a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5559a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5560a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5561a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5562a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5563a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5564a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5565a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
556672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
556772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
556872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
556972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
557072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
557172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
557272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
557372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
557472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
557572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
557672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
557772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
557872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
557972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
558072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
558172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5582e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5583e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5584e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5585e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5586b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5587b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5588e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5589e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5590e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5591e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5592b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5593b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5594b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5595b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5596b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5597b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5598b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5599b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5600b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5601b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5602b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5603b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5604b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5605b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5606b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5607b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5608e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5609e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5610a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5611a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5612a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
56136507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
56146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5615d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
56166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
56176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
56186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
56196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
56206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
56216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
56226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
56236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5638349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
564131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
564231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
56443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5663f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5668f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5679f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5686349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5687e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5689349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
56903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5691349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5692349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
57073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5711f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5729cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5730cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5731cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
573229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5733cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5734cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5735cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5736251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5737d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5738755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5739755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5740755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5741755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5742755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5743755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5744755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5745755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5746cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
575331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
57543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5757349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5758349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5759349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5760349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5776f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
57775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
57785778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5781f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5809f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
58103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
581131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
58125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
581331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
58255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5831349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5832349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5833349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5834349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5835349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5836349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5837349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
58420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
58445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58520167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
58530167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5854bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5855bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5856bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5857bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5858bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5859bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5860bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5881f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5913f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
59143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5925c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5937f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5941f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
59423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5972f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
59747a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5975d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5976d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5985e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5986e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5987e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5988e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5989e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6001349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6002349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
6003349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
6004349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6005609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6006349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6007349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6008349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6009349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
60103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6011349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6012349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6013349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6014349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6015349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6016349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6017349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
60417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
60427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
60437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
60447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6046d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6052dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6053dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6054f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6055f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6056f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6057f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6063