ACodec.cpp revision 1dcdfead2971c1fa7c02f24ba86f706890c9f99e
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
271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
40afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
53496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
54f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
98f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
119609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
132609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
138609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
206784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
232ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
238c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
245ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
304054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
305054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
313349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
314349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
324349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
406afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
407609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
4098db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
411308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4129806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4149806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4159806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
416e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4179806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
419054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
420054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
421a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42294ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
42437b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
4252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
426609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
427ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
428ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
443dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
4571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
4621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
463a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
464a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
465a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
466a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4675778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4691d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
4801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
4811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
4821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
4841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
4851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
4871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
4881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
4891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
4901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
4911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
4947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
4987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5005778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
5011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
504f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
5057a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
5061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
509f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
5101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
5141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
515c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
516c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
51730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
51830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
5191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
52030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
523496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
5241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
525496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
526496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5304dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5324dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, this))->post();
5364dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5374dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5384dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
5401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
5421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
5431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
5441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
5451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
5461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
5471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
5501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
5511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
5521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
5531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
5561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
5571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
5581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
5591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
5601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
5631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
5641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
5651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
5661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow);
5691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
5701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
5711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
5741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
5751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
5761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
5771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
5781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
5791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
5801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
5811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
5821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
5831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
5851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
5861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
5871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
5881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
5911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
5921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
5931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
5941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
5961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
5971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
5981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
5991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
6031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
6041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
6051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
6061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
6071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mStoreMetaDataInOutputBuffers
6081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
6101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
6111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
6131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
6151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
6161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
6171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
6181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
6191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
6201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
6241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (!mStoreMetaDataInOutputBuffers) {
6251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
6261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            const BufferInfo &info = buffers[i];
6271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
6291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
6301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), -1);
6311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
6321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
6331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
6341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
6351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
6361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
6371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
6381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
6401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
6411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
6665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
669609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
6705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
6715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
6725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
6785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
681ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
682ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
684afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
685afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
686afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
687afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
6881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
689308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
690308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
691ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
692ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
693ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
694ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
695ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
696ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
697ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
698308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
699308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
700308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
701308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
702ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
7035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
704ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
7055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
706ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
707ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
708ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
709ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
710ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
7115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
7135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
7141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
7151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
723d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
726eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
727eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
728eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
730eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
732eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
735eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setNativeWindowSizeFormatAndUsage(
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ANativeWindow *nativeWindow /* nonnull */,
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        int width, int height, int format, int rotation, int usage) {
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = native_window_set_buffers_dimensions(nativeWindow, width, height);
745ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (err != 0) {
7461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffers_dimensions failed: %s (%d)", strerror(-err), -err);
747ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        return err;
748ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    }
749ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar
7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffers_format(nativeWindow, format);
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
7521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffers_format failed: %s (%d)", strerror(-err), -err);
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int transform = 0;
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if ((rotation % 90) == 0) {
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        switch ((rotation / 90) & 3) {
7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            case 1:  transform = HAL_TRANSFORM_ROT_90;  break;
7601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            case 2:  transform = HAL_TRANSFORM_ROT_180; break;
7611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            case 3:  transform = HAL_TRANSFORM_ROT_270; break;
7621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            default: transform = 0;                     break;
763e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
764e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
765e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffers_transform(nativeWindow, transform);
7673c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffers_transform failed: %s (%d)", strerror(-err), -err);
7691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
777bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = nativeWindow->query(
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &queuesToNativeWindow);
780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
7811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("error authenticating native window: %s (%d)", strerror(-err), -err);
782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
7905a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    int consumerUsage = 0;
7911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(nativeWindow, NATIVE_WINDOW_CONSUMER_USAGE_BITS, &consumerUsage);
7925a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    if (err != 0) {
7935a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        ALOGW("failed to get consumer usage bits. ignoring");
7945a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        err = 0;
7955a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    }
7965a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
7971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int finalUsage = usage | consumerUsage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
7981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(ACodec) + %#x(Consumer) = %#x", usage, consumerUsage, finalUsage);
7991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_usage(nativeWindow, finalUsage);
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
80129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_scaling_mode(
8061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
8071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
8081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_scaling_mode failed: %s (%d)", strerror(-err), -err);
8091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGD("set up nativeWindow %p for %dx%d, color %#x, rotation %d, usage %#x",
8131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, width, height, format, rotation, finalUsage);
8141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
8151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
8161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
8181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
8191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
8201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
8211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
8231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
8241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
8261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
8301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
8311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
8321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
8331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
8341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
8351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
8371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
8391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
8401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
8431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
8441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
8451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
8461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
8471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
8481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
8491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
8501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
8511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
8531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
8541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
8551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
8561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
8571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
8581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
8601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
8611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
8631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
8641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
8661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
869ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
870ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
871ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
872ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
873ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
874ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
875ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
876ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
877ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
878ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
879ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
880ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
881ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
882ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
883ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
885258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
886258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
888258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
889258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
89029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
891258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
892258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
893258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
894258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
895e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
896e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
8971faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
8981faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
899e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
900e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
901e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
902e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
903e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
904e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
905e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
9061faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
9071faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
908e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
909e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
910258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
911258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
912258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
913258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
914e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
915e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
916e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
917e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
918e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
919609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
920e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
921e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
922e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
923258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
924258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
925258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
926258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
93129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
936054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
937054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
938054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
940054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
942054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
943054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
944054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
946054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
947e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
948054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
9493298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
9503298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
9513298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
9523298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
9533298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
954609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
956054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
959054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
9608ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
9611e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
96329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
96874006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
96974006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
97174006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
97274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
97374006804065941841883c4b46ee785070164023fJamie Gennis
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
978609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
97974006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
98374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
98474006804065941841883c4b46ee785070164023fJamie Gennis
985609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
99774006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
999054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1000054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1001054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
10063fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
10073fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
10083fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
10093fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10123298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    if (!mStoreMetaDataInOutputBuffers) {
10133298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
10143298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
10153298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
10163298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1020054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
1021054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1022054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1023054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1024054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1025054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1026e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1027054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1028609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
1029054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
1030054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1031054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
1032054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1033054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1034054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
1035054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1036054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
1037054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1038054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
1039054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
1040054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1041054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
1042054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
1043054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
1044054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
1045054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1046054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
1047054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
1048054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
1049054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1050054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
1051054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1052609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1053054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1054054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1055054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1056054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1057054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1058054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1059054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1060054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
1061054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
1062054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
1063054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1064054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1065054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
1066054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
1067054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
1068054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1069609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1070054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
1073054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
1074054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
1075054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1076054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1077054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
1078054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1079054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1083609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
10871e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10893fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
10903fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10943fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1097f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
10988ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1100ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1101ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1102ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1103ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1104ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1105ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1106ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
11071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
110829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
1109c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
1110c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1117054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
1118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1126054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1127054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1128054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1129054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1130054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1131054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1132054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1133054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1134054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1135054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1136054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
1137054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
1138054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1139054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
1140054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
1141054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
1142054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1143d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
1144d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
1145d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
1146054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1147d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
1148d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
1149d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
1150d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
1151d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1152d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1153ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1154054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
1155d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
1156d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1176349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11812ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
11822ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
11832ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
11842ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1192f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
12003fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1212f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
12422944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
12432944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
12442944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
12452944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1252729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1253729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1254bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1255bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1256c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1257c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1258c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1259c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
12622472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
12632472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
126894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
126994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
127094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
127194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1272ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1273ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
12742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
12752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1276ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1277ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1278774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1279774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
128097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
128197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
12828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
12838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
13185ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1335e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
13364e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1337e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13408db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
13482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
13492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
13502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1355d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1357d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1358d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1359d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1360d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1361308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1362308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1363d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1365308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1367d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1368308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
13693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
13703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
13713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
13723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
13733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
13743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
13753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
13763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
13773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
13793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
13803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
13813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
13823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
13843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
13853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
13863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
13883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
13893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
13903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
13913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
13923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
13933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
13943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1395308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1396308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1397308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1398308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
13998db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1400308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1401308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1402308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1403308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1404308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1405308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1406308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1407308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1408308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1409308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1410308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1411308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1412308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1413308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1414a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1415a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1416a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1417a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1418a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1419a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
142094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
142194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
14222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
14232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
14242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
142537b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
142637b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
142737b2b389139ed638831e49708c947863eef631efRonghua Wu        }
142837b2b389139ed638831e49708c947863eef631efRonghua Wu
14292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
14302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
143194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
143272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
143372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
143472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
143572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
143672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
143772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1438308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1439308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
14403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1441054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
14420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
14433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1444054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1445e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1446e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
14471713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
14481713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
14491713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
14501713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
14511713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
14521713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
14531713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
14541713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
14551713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
14561713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1457e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
14583a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
14591de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
14601de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
14615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14626597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
14636597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
14646597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
14656597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
14666597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
14676597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
14686597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
14696597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
14706597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
14716597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
14726597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
14736597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
14746597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
14756597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
14766597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
14776597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
14786597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
14796597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
14805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
14815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
14825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
14835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1484ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
14855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
148697827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
148797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
14885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
14895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
14905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
14915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
149297827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
14935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
14945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1495fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1496fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1497d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1498d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1499d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1500d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1501d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1502d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1503d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1504d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1505d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
15063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
15073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1508d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1509d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1510d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1511d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1512d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1513d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
15145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1515ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1516ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1517ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
15183fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
15193fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
15203fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
15213fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
15223fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
15233fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
15243fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
15253fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
15263fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
15275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
15285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
15295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
15305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
15315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1532fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1533e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
15355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
15365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
15375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
15395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
15405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
15415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
15425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
15435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
15455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
15465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
15475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
15485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
15495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
15505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
15515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
15525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
15535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
15545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
15555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
15575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
15585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
15595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
15605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
15615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
15625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
15645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
15655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
15665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
15675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
15685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
15695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
15705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
15715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
15725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
15735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
15745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1575e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
15765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
15775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
15785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
15795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
15805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
15815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
15825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1583fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
15840167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
15855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
15865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
15875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
15885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
15895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
15900167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1591e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1592e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1593e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1594e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1595e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1596e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1597e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1598054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1599054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1600308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
16013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
16023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
16033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
16043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
16053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
16063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
16110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
16153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
16163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
16191de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
16201de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            CHECK(mNativeWindow != NULL);
16213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
16243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
16253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        CHECK_EQ((status_t)OK, initNativeWindow());
16263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
16283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
16293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
16303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
16313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
16323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
16333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
16343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
16353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK(outputFormat->findInt32("color-format", &colorFormat));
16363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
16373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
16383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
16393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
16403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
16413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
16423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
16433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
16443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
16453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
16463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
16473a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
16483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
16493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
16503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
16513a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
16523a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
16533a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
16543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
16553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
16563a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
16573a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
16583a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
16593a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
16603a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
16613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
16623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
16633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
16643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
16653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
16663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
16673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
16683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
16693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
167042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
167142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
167242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
167342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
167442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
167542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
167642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
167742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
167842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
167942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
168042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
168142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
168242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1689aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1690b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
16918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
16922965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
16938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1694ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1695ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1696ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1697aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1698aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1699aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1700b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1701b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1702b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1703ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
17048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
17058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
17068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17072965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
17082965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
17092965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
17102965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
17118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
17128045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17138045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
17148045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17158045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
17168045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
17188045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
17208045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17218045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
17228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17238045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
17248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
17268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
17288045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
17298045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
17308045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
17318045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1732ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
17334471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
17342965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
17352965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1737729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1739729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1741729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1742729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1743729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1744729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1745729de186450f78c099637e1fce743fe531862c52Andreas Huber
1746729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
175017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
175117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
175217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
175317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
175417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
1757ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
17582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
17592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
17602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
17612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
17622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
17632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
17642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1765516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1766cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1767cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1768516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1769cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
17702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1771516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1772516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1773516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
17742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
17752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1776516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1777516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1778516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
17792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
17802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
17812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1782516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1783516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
17842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1785ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1786ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1787ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1788ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1789ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1790ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1791ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1792ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1793ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
179497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
179597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
179697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
179797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
179897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
179997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
180097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
180197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
180297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
18038a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
18048a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
18058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
18068a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
18078a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
18088a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
18098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
18108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
18118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1813729de186450f78c099637e1fce743fe531862c52Andreas Huber
18144471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
18154471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
18164471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
18174471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
18188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
18198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
18208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
18219806555d3930be43e11106281dee354820ac1c88Andreas Huber
18228b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
18238b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
18248b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
18258b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
18269806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
18279806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
18289806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
18299806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
18309806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
18319806555d3930be43e11106281dee354820ac1c88Andreas Huber
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18398b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
18408b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
18418b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
18428b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
18438b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1844ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
1845ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
1846ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
1847ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
1848ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
1849ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1850ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
1851ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
1852ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1853ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
18544e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
18554e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1856e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18648b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
18658b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
18668b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
18678b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
18688b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
18698b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
18708b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
18718b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
18728b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
18738b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
18748b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
18758b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
18768b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
18778b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
18788b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
18798b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
1880ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
1881ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
1882ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
1883ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1884ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
1885ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
1886ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
1887ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1888ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1889ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
1890ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
1891ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
1892ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
1893ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
1894ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
1895ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1896ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
1897ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
1898ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
1899ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
1900ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
1901ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
1902ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
1903ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
1904ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
1905ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
1906ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
1907ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
1908f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1972aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
19738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
19742965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
19752965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1976ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1977ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1978ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1979ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2040aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2042b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2043b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2044b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2045b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2046b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2047b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2048b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2049b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2050b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2051b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2052b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2053b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2054b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2055b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2056b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2057b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2058b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2059b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2060b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2061b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2062b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2063b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2064b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2065b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2066b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2067b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2092ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2093ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2094ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2095ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2096ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
20998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
21008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
21018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
21028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
21038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
21048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
21052965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
21068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
21078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
21088045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
21098045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
21108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
21118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
21128045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
21138045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
21148045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
21158045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
211897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
211997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
212097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
212197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
212297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
212397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
212497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
212597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
212697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
212797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
212897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
212997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
213097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
213197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
213297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
213397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
213497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
213597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
213697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
213797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
213897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
213997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
214097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
214197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
214297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
214397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
214497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
214597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
214697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
214797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
214897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
214997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
215097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
215197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
215297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
215397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
215497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
215597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
21568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
21578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
21588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
21598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
21608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
21628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
21638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
21648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
21668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
21678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
21688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
21698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
21718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
21728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
21738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
21758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
21768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
21778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
21788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
21798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
21818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
21828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
21838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
21858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
21868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
21888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
21898a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
21908a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
21918a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
21928a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
21938a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2240729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2241729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2243729de186450f78c099637e1fce743fe531862c52Andreas Huber
2244729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2245729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2246729de186450f78c099637e1fce743fe531862c52Andreas Huber
2247729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2248729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2249729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2250729de186450f78c099637e1fce743fe531862c52Andreas Huber
2251729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2256729de186450f78c099637e1fce743fe531862c52Andreas Huber
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2260729de186450f78c099637e1fce743fe531862c52Andreas Huber
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2265729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2266729de186450f78c099637e1fce743fe531862c52Andreas Huber
226717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2270729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
227117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2272729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2273729de186450f78c099637e1fce743fe531862c52Andreas Huber
22742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
22752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
22762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
22772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
22782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
22792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
22802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
22812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
22822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
22832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
22842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
22852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
22862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
22872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
22882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
22892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
22902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
22912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
22922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
22932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
22942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
22952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
22962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
22972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
22982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
22992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
23002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
23012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2302729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2303729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2304729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2305729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2306729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2307729de186450f78c099637e1fce743fe531862c52Andreas Huber
2308729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2309729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2310729de186450f78c099637e1fce743fe531862c52Andreas Huber
2311729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2312729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2313729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2314729de186450f78c099637e1fce743fe531862c52Andreas Huber
2315729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2316729de186450f78c099637e1fce743fe531862c52Andreas Huber
2317729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2318729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2319729de186450f78c099637e1fce743fe531862c52Andreas Huber
2320729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2321729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2322729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2323729de186450f78c099637e1fce743fe531862c52Andreas Huber
2324729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2325729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2326729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2327729de186450f78c099637e1fce743fe531862c52Andreas Huber
2328729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2329729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2330729de186450f78c099637e1fce743fe531862c52Andreas Huber
2331729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2332729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2333729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2334729de186450f78c099637e1fce743fe531862c52Andreas Huber
2335729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2336729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2337729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2338729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2339729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2340729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2341729de186450f78c099637e1fce743fe531862c52Andreas Huber
2342c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2343c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2344729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2345729de186450f78c099637e1fce743fe531862c52Andreas Huber
2346729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2347729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2348729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2349729de186450f78c099637e1fce743fe531862c52Andreas Huber
23505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
235197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
23525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
23535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
23545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
23555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
23565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
23575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
23585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
23595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
23605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
23615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
23625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
23635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
23645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
23655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
23665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
23675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
23685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
23695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
23705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
23740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
23750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2393229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2394229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
23950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
23960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
23970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
23980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2399229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2400229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2401229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2402229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2403229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
24430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
24440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
24450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
24460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
24470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
24480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
24490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
24500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
24510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
24520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
24530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
24540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
24550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
24560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
24570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
24620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
24630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
24660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
24670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
24680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
24690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
24700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
24710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
24720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
24730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
24740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
24750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
24760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
24770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
24790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
24800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
24820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
24830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
24850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
24860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
24870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
24880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
24890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
24900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
24910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
24920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
24930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
24940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
24950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
24960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
24970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
24980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
24990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
25000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
25010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2507e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
25122472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
251694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
251794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2547e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
25530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
255489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
255589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
255689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
255789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
255889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
255989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
257589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
257689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
257789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
257889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
25790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
258089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
258189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
258289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
25830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
258489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
258589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
25860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
258789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
259378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
259478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
259578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
259678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
259778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
259878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
259978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
260078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
260178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
260378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
26872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2692a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2693a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2694a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2695a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2696a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2766c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2767c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2768c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2769c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
277089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
277189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
277289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
277389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
277489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
27850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
27860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
27870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
27880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
27900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
27910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
27920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
27930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
27940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
27950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
27960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
27970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
27980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
27990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
28010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
28020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
28030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
28040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
28070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
28090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
28100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
28110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
28130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
28140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
28160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
28170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
28180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
28190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
28200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
28245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
283196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
283296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
283396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
283496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
283596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
283696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
283796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
283896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
283996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
284796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
284896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
28915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
28925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
291296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
292896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
292996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
29415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
29425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
29445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
29455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
29545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
29555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
29605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
29625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
29635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
29695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
29745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
29835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
298896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
29895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
29955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2997a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2998a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2999a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3000a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3001a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3002a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3003a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3004a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3005a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3006a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3007a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3008a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3009a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3010a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3011a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3012a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3013a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3014a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3015a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3016a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3017a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3018a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3019a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3020a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3021a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3022a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3023a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3024a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3025a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3026a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3027a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3028a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3029a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3030a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3031a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3032a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3033a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3034a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3035a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3036a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3037a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3038a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3039a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3040a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3041a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3042a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3043a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3044a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3045a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3046a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3047a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3048a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
30495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
30505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
30535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
30545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
305696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
305796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
30585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
30595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
30615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
30625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
30655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
30680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
30690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
30700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
30710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
30720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
30730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
30740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
30750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
30760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
30770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
30835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
30905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
30915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
30935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
30945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
30955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
30965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
31005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
31025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
31035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
31107c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
31117c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
31127c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
31135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
31145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
31205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
31215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
31225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
31235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
31375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
31455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
31465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
31485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
31495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
315496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
31555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3157c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3158c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3159c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3160c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3161c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3162c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3163c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3164c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3165c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3166c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3167c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3168c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3169c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3170c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3171c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3172c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3173c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3174c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3175c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3176c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3177c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3178c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3179c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3180c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3181c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3182c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3183c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3184c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3185c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3186c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3187c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3188c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3189c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3190c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3191c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3192c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3193c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3194c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3195c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3196c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3197c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3198c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3199c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3200c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3201c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3202c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3203c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3204c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3205c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3206c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3207c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3208c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3209c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3210c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3211c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3212c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
321389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
321489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
32154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
32164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
32174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
32184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
32194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
32204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
32214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
32224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
32234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
32244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
32254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
322689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
322789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
322889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
32294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
323089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
323189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
323289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
32334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
32344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
32354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
32364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
32374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
32384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
32404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
32414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
32434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
32444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
32454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
32464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
32474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
32484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
32494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
32504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
32514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
32524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
32534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
32544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
32554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
32574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
32594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
32604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
32614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
32624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
32644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
32664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
32674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
32684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
32704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
32714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
32724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
32734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
32744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
32754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
32764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
32784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
32794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
32804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
32824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
32834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
32844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
32854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
32864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
32874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
32884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
32894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
329089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
329189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
329289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
32935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
32945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
32955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
32965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
32975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
32985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
33005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
33015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
33025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
33035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
33045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
33055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
33075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
33085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
33115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
33125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
33145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
33155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
331996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
332096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
33215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
33225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
33235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
33245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
33265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
33275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
33285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
33315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
333396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
33345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
33355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
33375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
33385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
33395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
33425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
33435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
33445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
33455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
33475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
33485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
33495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
33525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
33555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
33565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
33575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
33585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
33595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
33615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
33625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
33635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
336778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
336878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
339678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
339778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
339878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3416d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3417d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3418d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3419d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3420d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3421d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3422d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3423d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3424d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3425d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3426d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3427d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3428d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3429d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
34307e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
34317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
34327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
34347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
34357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
34377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
34387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
34397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
34407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
34427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
34437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
34447e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
34457e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
34467e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
34477e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
34487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3449e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
34507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3451c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3452c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3453c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3454c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
34557e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
34567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
34577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3465609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3495229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
349603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
349703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
349803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
349903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
350003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
350103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
350203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
350303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
350403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
350503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
350603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
350703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
350803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
350903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
35105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
35115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
351203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3513229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
351403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
351503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3516b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3517b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3518b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3519b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3520b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3521b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3522b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3523b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3524b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3525b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3526b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3527b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3528b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3529b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
353003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
353103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
353203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
353303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
353403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
353503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
353603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
353703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
353803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
353903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
35405a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
35415a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
35425a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
35435a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
35445a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
35455a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
35465a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35475a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
35485a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
35495a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
35505a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
35515a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
35525a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35535a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
35545a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
35555a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
35565a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
35575a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
35585a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
35595a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
35605a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
35615a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
35625a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
35635a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
35645a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
356503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
356603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
356703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
356803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
356903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
357003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
357103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
357203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
357303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
357403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
357503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
357603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
357703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
357803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
357903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
358003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
358103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
358203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
358303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
358403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
358503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
358603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
358703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
358803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
358903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
359003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
359103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
359203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
359303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
359403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
359503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
359603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
359703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
359803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
359903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3600229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3601229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3602229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3603229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3604229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3605229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3606229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3607229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3608229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3609229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3610229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3611229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3612229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3613229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3614229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3615229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3616229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3617229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3618229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3619229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3620229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3621229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3622229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3623229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
36240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3625229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3626229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3627229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3628229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3629229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3630229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3631229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3632229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
36330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3634229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3635229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3636229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3637229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3638229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3639229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3640229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3641229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3642229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3643229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3644229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3645229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3646229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3647229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3648229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3649229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3650229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3651229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3652229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3653229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3654229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3655229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3656229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3657229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3658229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3659229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3660229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3661229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
366203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
366303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3664e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3665e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
366631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
366731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3668e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
366931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
367031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
367131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
367231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
367331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3674e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3675e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
367631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
367731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
367831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
367931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
368031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3681e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3682e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3683e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3684e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3685e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3686e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3687e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3688e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3689e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3690e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
36910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
36920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
36930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
36940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
36950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
36960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
36970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
36980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
36990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
37000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
37010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
37020d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
37030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
37040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
37050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
37060d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
37075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
37085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
37095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
37105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
37115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
37125a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
37135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
37140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
371503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
371603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
371791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
371891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
371991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
372091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
372191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3722e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3723e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
372491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3726e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
372791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
372891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
372991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
373091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3731e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3732e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3733e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3734e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3735e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3736e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
373731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3738e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3739e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3740e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3741e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3743e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3745e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3746577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3747577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3748577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3749e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3750e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3751e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3752e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3753e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
37544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
37554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
37564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
37574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
37584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
37594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
37604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
37614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
37624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
37634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
37644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
37654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
37664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
37674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
37684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
37694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
37704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
37714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
37724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
37734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
37754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
37784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
37804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
37834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
37854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
37884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
37894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
37904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
37914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
37924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
37934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
37944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
37954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
37964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
37974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3798e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3799e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3800e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3801e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3802e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3803e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3804e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3805e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3806e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3807e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
381031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3811e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
38135a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
38145a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
38155a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
38165a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
381731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
381831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
381931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
382031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
382131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
382231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
382331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
382497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3829e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
383614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
383914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
384014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
384114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
384214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
384314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
384414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3847e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3848e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3850e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3851e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
38528b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3853e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
38548b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
38559806555d3930be43e11106281dee354820ac1c88Andreas Huber
3856e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3857e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3861e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3862e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3863e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3864e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3865e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3866e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3867e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3868e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3869e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3870e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3871e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3877e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
38789806555d3930be43e11106281dee354820ac1c88Andreas Huber
3879e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3881e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3882e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3883e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3884e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3885e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3886e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3887e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3888e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3889e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3890e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3891e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3892e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3893e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3894e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3895e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3896e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3897e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3898e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3899e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3900e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3901e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3902e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3903e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3904e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3905e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3906e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3907e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3908e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3909e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3910e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3911e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3912e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3913e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3914e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3915e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3916e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3917e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3918e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3919e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3920e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3921e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3922e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3923e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3924e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3925e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3926e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3927e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3928e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3929e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3930e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3931e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3932e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3933e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3934e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3935e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3936e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3937e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3938e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3939e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3940e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3941e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3942e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3943e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3944e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3945e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3946e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3947e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3948e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3949e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
395097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
395197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
395297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
395397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3954e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
395597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
395697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
395797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
395897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
395997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
396097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
396197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
396297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
396397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
396497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
396597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
396697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3967e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
39688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
39698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
39708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
39718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
39728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
39738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
39748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    CHECK_EQ((status_t)OK, mOMX->getParameter(
39758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            mNode,
39768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
39778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            &params,
39788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            sizeof(params)));
39798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
39808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
39818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
39828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
39838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
39848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
39858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
39868c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
39878c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
39888c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
39898c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
39908c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
39918c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
39928c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
39938c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
39948c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
39958c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
39968c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
39978c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
39988c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
39998c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
40008c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
40018c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
40028c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
40038c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
400410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
400510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
400610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
400710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
400810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
400910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
401010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
401110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
401210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
401310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
401410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
401510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
401610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
401710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
401810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
401910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
402010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
402110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
402210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
402310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
402410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
402510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
402610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
402710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
402810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
402941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
403041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
403141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
403241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    OMX_AUDIO_PARAM_MP3TYPE params;
403341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
403441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
403541d3f579d2c166984958263533284209b90c87d5Marco Nelissen
403641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    CHECK_EQ(mOMX->getParameter(
403741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                mNode, OMX_IndexParamAudioPcm,
403841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                &params, sizeof(params)),
403941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                             (status_t)OK);
404041d3f579d2c166984958263533284209b90c87d5Marco Nelissen
404141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
404241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
404341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("sample-rate", params.nSampleRate);
404441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
404510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
404610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4048e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
4049e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
4050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
405131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
405231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
405331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
405431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
405531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
405631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
405731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4058e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4059e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4060e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4061e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
40624e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
4063e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4064e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4065e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
4066e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4067e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4068e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
4069e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4070e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
4071e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4072e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
4073e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
4074e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
4075e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4076e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
4077e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4078e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
4079e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
4080e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
4081e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
4082e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4083e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4084e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4085ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4086e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4087e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4088e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
4089e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
4090e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
4091e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4092e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
409331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
409431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
409531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
409631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
409731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
40985778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4099cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4100d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4101251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4102251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4103251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4104251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4105251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4106251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4107251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4108251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
4109251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
4110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
41115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
4112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4113cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
4114cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
4115cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
4116bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
4117bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
4118bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
4119bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
4120bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
4121bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4122bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
4123bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
4124bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
4125bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
4126bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
4127bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4128bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
4129bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4130bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4131bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4132bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4133bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
4134bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
4135bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4136bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
4137bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4138bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4139bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4140bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
41411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = setNativeWindowSizeFormatAndUsage(
41421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNativeWindow.get(), 1, 1, HAL_PIXEL_FORMAT_RGBX_8888, 0, GRALLOC_USAGE_SW_WRITE_OFTEN);
4143ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (err != NO_ERROR) {
41441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("error pushing blank frames: set format failed: %s (%d)",
4145bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4146bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4147bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4148bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4149bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
4150bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
4151bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4152bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
4153bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
4154bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4155bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4156bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4157bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
4158bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
4159bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4160bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
4161bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
4162bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
4163bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4164bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4165bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
4166bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
4167bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
4168bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
4169bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
41701e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
4171bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4172bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
4173bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4174bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4175bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4176bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4177bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
4178bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4179bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
4180bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
4181bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
4182bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4183bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
4184bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4185bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4186bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4187bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4188bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
4189bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4190bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
4191bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4192bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
4193bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4194bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4195bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4196bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4197bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
41981e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
4199bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4200bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
4201bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4202bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4203bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4204bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4205bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
4206bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4207bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4208bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
4209bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4210bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4211bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
4212bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
42131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
4214bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4215bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4216bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
4217bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4218bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
4219bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4220bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4221bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4222bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
4223bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
4224bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
4225bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4226bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4227bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
4228bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4229bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4230bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4231bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4232bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
4233bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4234bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4235bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
4236bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4237bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4238bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4239bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4240bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
4241bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4242bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
4243bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4246eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4247eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4248eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4249496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4250496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4251496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4252496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4253496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4254496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4255496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4256496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4257496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4258496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4259496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4260496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4261496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4262496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4263496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4264496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4265496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4266496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4267eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4268eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4269eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4270eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4271eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4272eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4273eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4274eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4275eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4276eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4277eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4278eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4279eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4280eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4281eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4282eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4283eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4284eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4285eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4286eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4292ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4293ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
43171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
43181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
43191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
43201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
43221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
43231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
43251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
43271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
43281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
43291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
43301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
43311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
43327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
43337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
43347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4335251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
43367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
43377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
43387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
43397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
43407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4341ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4342ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4343251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4344ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4345ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4346ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4347ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4348ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
434930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
435030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
435130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
435230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
435330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
435430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
435530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
435630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
435730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
435830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
435930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
436030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
436130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43735e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
43745e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4375ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
43765e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
43775e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
43785e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
43795e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
43805e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4382609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43930af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
43940af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
43950af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
43960af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
43970af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
43980af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
43990af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
44000af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
44010af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
44020af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
44030af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4413609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4421609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4435784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4447ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4453ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4455251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4456251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4457251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4458251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4459251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4460251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4461251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
4467ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4468349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4469349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
447796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
447896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
447996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
448096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
448196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4512d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4513609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
45162d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4519609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4530609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
45312d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
45335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4534a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
45355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45362d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4537a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45407fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
45417fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
45427fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
45437fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
45447fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
45457fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
45467fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
45477fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
45483831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
45492d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
45535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
45545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
45555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
45565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
45665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4567dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4568dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4569dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4570dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
45775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
45895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
45905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
45915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4593ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4602078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4603ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4604078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
46055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4606ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
46075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4608078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4610ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4611ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4613ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4614ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4616078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4617349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4621d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4625054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4626054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4627054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4628054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4629054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4634e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4635054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4636054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4637054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
46505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
46515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
46525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
46535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
46545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
46565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
46575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4659dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
46603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4661dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4662dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4663dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
46643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4665dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4666dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4668ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4669349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4670349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4683dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4687625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4688625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4689625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4690625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4727784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4728609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
47295778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4730349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4732d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4733d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4734d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4735d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4736d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4737d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4738d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4739d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4764a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4765a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4766609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
47675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4768349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
47695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
47705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
47715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
47745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
47755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
477631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4777577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
47781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
4779577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
47804bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4781577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
47825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4784308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4785308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4786308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4787308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4788308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4789308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4790308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4791308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4792308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4793496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
479421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4795496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4796496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4797496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
47985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
479921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48018b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
48028b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
48038b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
48045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4807d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4808609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
48092d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
48105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4812609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
48175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
48215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
48225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4824d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4825dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4848609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4854577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4855577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4856577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4857577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4858577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4859577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4860577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
48636aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
486479ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
48656fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4868fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4869fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4870fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4871fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4872fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4873fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4874fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4875fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
487647aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4877fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4878fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4879fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4880fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4881fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
48825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4883fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4884fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4885fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4886fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4887fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
48885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
48901e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4891cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4892cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4893251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4894cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4895cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
48976fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
48986fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
48996fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
49006fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4930c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4931609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4932c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4933349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4934c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4935c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4937c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4938c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4956f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4960c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4961c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4962ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4963ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4964f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4965ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4966ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4967ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4968ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4969ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
4970ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4971ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4972ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4973308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4974ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4975c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4976c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
49905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
49915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
49925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
49935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
49945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
49955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4998c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4999c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5000c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
500154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
500254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
5003c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5005d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5009c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
5013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5015d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5019c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
502230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
502330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
502430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
502530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
502630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
502730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
502830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5036f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5038c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
5039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
5040c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
5041c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
50425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
50435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5044c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
50455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
50465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5047ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
50485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
505048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
505148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
505248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
505348a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
5054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
5056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5058ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5059ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
5060f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5061ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
5062ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
5063ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5064ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5065ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5066e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
50675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
5069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
5071d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
50727791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
50735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
5074e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
5075e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5076e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
5077afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
5078e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
5079e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
5080e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
5081afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
50825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
50835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
50845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
50865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
50875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
50885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
50905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
50915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
50925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
50935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
5094e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
50955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
50961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
50971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
5098ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
50991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
51009f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu    status_t err = OMX_ErrorComponentNotFound;
51011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
51021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
5103e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5104e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5106da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
5107078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
5108078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
51099f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
5110078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
5111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
51131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
51147a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
51157a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
51161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
51171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5118ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
51191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
51201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5121ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
51225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
51239f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
51249f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
51255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
51269f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
51275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5128c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
512952e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
5131c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
5132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51331d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatOMXMessage, mCodec);
5134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
5135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
5137ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
5138ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5139ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
5140ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
51411713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
51420167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5143ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
5144ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5145afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
5146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
5147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
5148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
51505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5151d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
51525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
51535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
51545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5155c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5156c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
5157c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5158c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
51595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
51605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5161c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
5162c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5163c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
5164c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
5165c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5166c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5167c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
5168c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5169c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5170f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
5171f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
5172f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5173f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
5174f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5175054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
5176054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
5177a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
5178e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
5179e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
51804e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
5181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5183c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5187c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
519054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5191f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5192f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
5197c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
5198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5199c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
520254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
520354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5204d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
520554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
520654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
520754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
52217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
52227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
52237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
52247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
52257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
52267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
52277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5228c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5229c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5230c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5231c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5232c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5233c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5234c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5238c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5239c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
524154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5243c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5245c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5248c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5251d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
52665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
52675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
52685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5269ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
52705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
52725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
52735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
52755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5277c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5278c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5279c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5280251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
52825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
52855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5286d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5287e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5288e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
52895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
52905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5291c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
52935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
52945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
5296ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
52977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
52987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
52997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
5300d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
53017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
53027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
53037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
53047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
53057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
53067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
5307a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5308a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
5309a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5310a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5311a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5312a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5313a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5314a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5315a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5316a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5317a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5318a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5319a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5320a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5321a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5322a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5323a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
53242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
532594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
532694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
532794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
532894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
532994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
533094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
533194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
533294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
533394ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
533472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
533572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
53362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
53372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
53382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
533937b2b389139ed638831e49708c947863eef631efRonghua Wu    if (err == OK && mCodec->mMaxFps > 0) {
534037b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
534137b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
534237b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
534337b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
534437b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
534537b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
534637b2b389139ed638831e49708c947863eef631efRonghua Wu
534737b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
534837b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
534937b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
535037b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
535137b2b389139ed638831e49708c947863eef631efRonghua Wu        }
535237b2b389139ed638831e49708c947863eef631efRonghua Wu    }
535337b2b389139ed638831e49708c947863eef631efRonghua Wu
53542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
53552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
53562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
53572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
53582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
53592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
53602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
53612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
53622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
53632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
53642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
53652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
53662c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
53672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
53682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
53692c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
53702c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
53712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
537272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
537372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
537472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
537572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
537672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
537772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
537872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
537972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
538072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
538172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
538272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
538372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
538494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
538594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
538694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
538794ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
538894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
53897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
53907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
53917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
53927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
53937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
53947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
53957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
53967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
53977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
53987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
53997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
54007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
54017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
54027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
54045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
54055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
54065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
54075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5415f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
54203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5422cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5423cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
542429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5425cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5426cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5427cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5428251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
542991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
543091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5431cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
544672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
54546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
54556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
54566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
54576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
54586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
54596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
54606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
54616463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
54626463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
54636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
54646463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
54656463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
54666463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
54676463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
54686463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5469d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
54706463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
54716463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
54726463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
54736463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5503f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
55083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
551372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5520d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5521d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5522d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5523d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5524d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5525d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5526d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5527d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5528d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5529d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5530d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5531d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5532d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5533d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5534d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5535d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
55366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
55376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
55386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
55396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
55406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
55416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5568f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5569349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5570349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5573f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5574ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5578054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5579054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5580054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5581054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5582054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5583054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5584054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5585054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5586054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5587054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5588054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
55894dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
55904dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
55914dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5592054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5593054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5594054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5609ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] calling fillBuffer %u",
5610349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5611349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5620c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5621054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5622054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5623054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5624054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5625054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5627349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
56283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5629349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5630349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5631349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5632349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5633349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56363cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
56383cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
56393cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
56403cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
56413cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
56423cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
56433cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5644349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5645349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
56493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5664c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
566554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5666c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5667c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5668349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5669349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56827a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5683ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
5684d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5685d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5686d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5687d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5688d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5689d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5690349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5691349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5709496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5710496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5711496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5712496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5713496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5714496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5715496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5716496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5717496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5718496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5719496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5720a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5721a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5722a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5723a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5724a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5725a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5726a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5727a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5728a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5729a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5730a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5731a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5732a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5733a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5734a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5735a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5736a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
57377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
57387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
57396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
57407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
57417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
57427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
57437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
57444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
57454dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
57464dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
57474dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
57484dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
57494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
57504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
57514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
57524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
57534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
57544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
57554dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
57564dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5765a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5766a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5767530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5768a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5769a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5770a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5771a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5772a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5773a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5774a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5775a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5776a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5777a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5778a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5779a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5780a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5781a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5782a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5783a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5784a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5785a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5786a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
578772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
578872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
578972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
579072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
579172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
579272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
579372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
579472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
579572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
579672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
579772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
579872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
579972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
580072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
580172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
580272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5803e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5804e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5805e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5806e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5807b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5808b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5809e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5810e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5811e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5812e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5813b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5814b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5815b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5816b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5817b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5818b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5819b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5820b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5821b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5822b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5823b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5824b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5825b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5826b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5827b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5828b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5829e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5830e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
58318db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
58328db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
58338db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
58348db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
58358db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
58368db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
58378db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
58388db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
58398db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
5840a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5841a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5842a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
58436507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
58446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5845d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
58466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
58476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
58486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
58496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
58506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
58516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
58526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
58536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
586131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5868349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
587131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
587231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5874ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5893f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5898f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5909f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5916349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5917e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5919349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
59203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5921349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5922349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5936f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
59373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5941f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5959cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5960cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5961cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
596229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5963cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5964cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5965cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5966251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5967d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5968755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5969755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5970755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5971755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5972755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5973755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5974755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5975755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5976cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
598231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
598331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
59843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5987349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5988349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5989349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5990349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6006f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
60075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
60085778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
60403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
604131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
60425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
604331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
60555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
6057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6061349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6062349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
6063349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
6064349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
6065349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6066349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6067349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
60720af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
6073f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
60745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
6075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
6076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
6081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60820167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
60830167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
6084bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
6085bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
6086bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
6087bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
6088bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
6089bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
6090bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
6091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
6092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6095f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6102f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
6103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6111f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
61443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6155c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6167f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6171f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
61723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6177f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6202f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6204ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6205ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6206d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
6211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
6214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6215e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
6216e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
6217e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
6218e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6219e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
6221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
6222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
6223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
6224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6231349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6232349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
62331d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6234349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6235609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6236349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6237349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6238349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6239349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
62403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6241349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6242349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6243349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6244349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6245349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6246349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6247349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6255f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6261f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6267f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
62717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
62727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
62737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
62747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6276d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6282dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6283dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6284f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6285f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6286f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6287f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6293