ACodec.cpp revision 17c39e708ed657b8fa66f8acce5128e51696915c
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
35a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
38afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
56251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
57251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
58251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
97f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
118609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        msg->setInt32("node", omx_msg.node);
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
131609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
137609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                msg->setInt32(
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
205784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung            int64_t timeUs);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
216ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
218ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
219ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
220ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
221ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
223ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
224ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
225ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
226ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
227ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
228ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
229ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
230ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
231ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
244ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
256c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
257c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
258c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
259c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
304054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
312349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
313349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
322349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
405afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
406609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
409308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
4109806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
41154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4129806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4139806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
414e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4159806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
416054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
417054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
419a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
42094ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
4212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
4222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
423609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
424ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
425ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
440dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
459a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
460a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
462a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
463a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4645778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4897a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
493f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
50130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
50230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
50330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, id()))->post(3000000);
50430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
507496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
508496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
509496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
510496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
5124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
5134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
5144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
5154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
5164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
5174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
5184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
5194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
5204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
5214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
5224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
531054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
532054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
533054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
534054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
535054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
545609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Allocating %u buffers of size %u on %s port",
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
558ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
560afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
561afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
562afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
563afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
565308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
566308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
569ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
570ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
571ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
572ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
573ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
574308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
575308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
576308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
577308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
578ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
580ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
582ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
583ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
584ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
585ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
586ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
599d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
602eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
603eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
604eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
606eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
608eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
617054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
643e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (mRotationDegrees != 0) {
644e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        uint32_t transform = 0;
645e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        switch (mRotationDegrees) {
646e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 0: transform = 0; break;
647e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 90: transform = HAL_TRANSFORM_ROT_90; break;
648e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 180: transform = HAL_TRANSFORM_ROT_180; break;
649e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            case 270: transform = HAL_TRANSFORM_ROT_270; break;
650e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            default: transform = 0; break;
651e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
652e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
653e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (transform > 0) {
654e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            err = native_window_set_buffers_transform(
655e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                    mNativeWindow.get(), transform);
656e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            if (err != 0) {
657e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                ALOGE("native_window_set_buffers_transform failed: %s (%d)",
658e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                        strerror(-err), -err);
659e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang                return err;
660e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            }
661e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
662e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
663e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
6653c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
6663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
6673c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
6685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
6693c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6703c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6713c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6725a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    int omxUsage = usage;
6733c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
6741713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang    if (mFlags & kFlagIsGrallocUsageProtected) {
675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
6975a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    int consumerUsage = 0;
6985a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    err = mNativeWindow->query(
6995a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            mNativeWindow.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS,
7005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            &consumerUsage);
7015a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    if (err != 0) {
7025a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        ALOGW("failed to get consumer usage bits. ignoring");
7035a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        err = 0;
7045a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    }
7055a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
7065a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec) + %#x(Consumer) = %#x",
7075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            omxUsage, usage, consumerUsage, usage | consumerUsage);
7085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    usage |= consumerUsage;
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
7113c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
71429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
718ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
719ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
720ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
721ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
722ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
723ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
724ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
725ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
726ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
727ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
728ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
729ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
730ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
731ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
732ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
734258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
735258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
737258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
738258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
73929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
740258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
741258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
742258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
743258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
744e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
745e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
7461faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
7471faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
748e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
749e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
750e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
751e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
752e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
753e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
754e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
7551faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
7561faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
757e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
758e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
759258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
760258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
761258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
762258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
763e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
764e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
765e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
766e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
767e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
768609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
769e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
770e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
771e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
772258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
773258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
774258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
775258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
78029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
796e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
798609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
8048ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
8051e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
80729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
81274006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
81374006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
81574006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
81674006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
81774006804065941841883c4b46ee785070164023fJamie Gennis
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
822609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
82374006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
82874006804065941841883c4b46ee785070164023fJamie Gennis
829609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
84174006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
8503fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
8513fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
8523fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
8533fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
865e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
867609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u meta buffers on output port",
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
873054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
874054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
875054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
877054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
878054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
881054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
882054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
891609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
893054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
894054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
898054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
900054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
901054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
902054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
903054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
904054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
907054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
908609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
909054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
910054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
911054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
913054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
914054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
915054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
916054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
917054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
918054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
922609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
9261e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9283fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
9293fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9333fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
936f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
9378ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
938054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
939ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
940ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
941ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
942ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
943ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
944ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
945ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
9461e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
94729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
948c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
949c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
951054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
956054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
965054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
966054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
968054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
971054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
972054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
975054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
976054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
978054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
979054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
981054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
982d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
983d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
984d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
985054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
986d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
987d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
988d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
989d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
990d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
991d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
992054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
993054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
994d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
995d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
996054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
997054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1015349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10202ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
10212ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
10222ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
10232ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
10393fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        cancelBufferToNativeWindow(info);
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1051f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
10812944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
10822944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
10832944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
10842944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1091729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1092729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1093bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1094bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1095c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1096c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1097c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1098c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
11012472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
11022472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
110794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
110894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
110994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
111094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1111ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1112ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
11132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
11142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1115ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1116ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1117774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1118774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
111997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
112097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
11218a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
11228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
11575ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
11754e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1176e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
11862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
11872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
11882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1199308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1200308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1202308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1203308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1204308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1206308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
12073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
12083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
12093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
12103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
12113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
12123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
12133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
12143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
12153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
12173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
12183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
12193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
12203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
12223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
12233a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12243a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12253a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
12263a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
12273a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
12283a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
12293a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
12303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
12313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
12323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1233308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1234308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1235308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1236308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1237308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1238308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1239308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1240308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1241308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1242308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1243308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1244308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1245308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1246308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1247308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1248308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1249308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1250308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1251a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1252a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1253a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1254a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1255a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1256a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
125794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
125894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
12592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
12602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
12612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
12622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
12632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
126494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
126572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
126672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
126772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
126872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
126972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
127072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1271308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1272308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
12733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1274054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
12750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
12763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1277054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1278e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1279e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
12801713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
12811713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
12821713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
12831713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
12841713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
12851713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
12861713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
12871713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
12881713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12891713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1290e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
12913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
12925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<NativeWindowWrapper> windowWrapper(
12935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                static_cast<NativeWindowWrapper *>(obj.get()));
12945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
12955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
12966597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
12976597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
12986597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
12996597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
13006597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
13016597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
13026597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
13036597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
13046597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
13056597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
13066597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
13076597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
13086597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
13096597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
13106597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
13116597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
13126597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
13136597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
13145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
13155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
13165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
13175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1318ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
13195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
132097827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
132197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
13225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
13235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
13245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
13255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
132697827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
13275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
13285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1329fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1330fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1331d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1332d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1333d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1334d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1335d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1336d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1337d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1338d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1339d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
13403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
13413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1342d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1343d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1344d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1345d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1346d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1347d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
13485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1349ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1350ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1351ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
13523fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
13533fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
13543fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
13553fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
13563fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
13573fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
13583fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
13593fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
13603fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
13615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
13625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
13635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    mNode, kPortIndexOutput, OMX_TRUE);
13645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
13655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1366fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1367e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
13695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
13705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
13715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
13735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
13745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
13755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
13765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
13775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
13795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
13805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
13815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
13825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
13835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
13845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
13855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
13865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
13875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
13885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
13895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
13915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
13925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
13935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
13945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
13955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
13965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
13975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
13985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
13995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
14005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
14015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
14025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
14035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
14045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
14055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
14065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
14075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
14085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1409e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
14105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
14115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
14125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
14135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
14145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
14155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mStoreMetaDataInOutputBuffers = true;
14165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1417fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
14180167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
14195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
14205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
14215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
14225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
14235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
14240167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1425e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1426e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1427e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1428e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1429e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1430e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1431e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1432054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1433054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1434308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
14353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
14363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
14373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
14383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
14393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
14403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
14450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14473a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
14493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
14503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14513a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14523a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
14533a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            sp<NativeWindowWrapper> nativeWindow(
14543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
14553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            CHECK(nativeWindow != NULL);
14563a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            mNativeWindow = nativeWindow->getNativeWindow();
14573a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14583a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            native_window_set_scaling_mode(
14593a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
14603a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
14613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
14633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
14643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        CHECK_EQ((status_t)OK, initNativeWindow());
14653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
14663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
14673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
14683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
14693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
14703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
14713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
14723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
14733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
14743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                CHECK(outputFormat->findInt32("color-format", &colorFormat));
14753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
14763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
14773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
14783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
14793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
14803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
14813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
14823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
14833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
14843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
14853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
14863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mStoreMetaDataInOutputBuffers) {
14873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE);
14883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mStoreMetaDataInOutputBuffers = false;
14893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
14903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
14913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
14923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
14933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
14943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
14953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
14963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
14973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
14983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
14993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
15003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
15013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
15023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
15033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
15043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
15053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
15063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
15073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
15083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
150942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
151042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
151142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
151242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
151342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
151442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
151542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
151642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
151742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
151842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
151942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
152042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
152142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1528aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1529b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
15308045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
15312965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
15328045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1536aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1537aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1538aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1539b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1540b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1541b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1542ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
15438045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
15448045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
15458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15462965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
15472965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
15482965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
15492965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
15508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
15518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
15538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
15558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
15578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
15598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
15618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
15638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
15658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15668045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
15678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
15688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
15698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
15708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
1571ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
15724471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
15732965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
15742965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1576729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1578729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1580729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1581729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1583729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1584729de186450f78c099637e1fce743fe531862c52Andreas Huber
1585729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
158917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
159017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
159117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
159217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
159317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
15962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
15972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
15982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
15992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
16002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
16012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
16022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
16032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1604516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1605cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
1606cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
1607516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
1608cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
16092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1610516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1611516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1612516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
16132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
16142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1615516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1616516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1617516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
16182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
16192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
16202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1621516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1622516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
16232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1624ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1625ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1626ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1627ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1628ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1629ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1630ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1631ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1632ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
163397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
163497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
163597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
163697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
163797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
163897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
163997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
164097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
164197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
16428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
16438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
16448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
16458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
16468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
16478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
16488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
16498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
16508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1652729de186450f78c099637e1fce743fe531862c52Andreas Huber
16534471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
16544471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
16554471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
16564471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
16578b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
16588b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
16598b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
16609806555d3930be43e11106281dee354820ac1c88Andreas Huber
16618b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
16628b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
16638b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
16648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
16659806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
16669806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
16679806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
16689806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
16699806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
16709806555d3930be43e11106281dee354820ac1c88Andreas Huber
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16784e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
16794e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
1680e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1681e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1682e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1683e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1684e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1752aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
17538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
17542965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
17552965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
1756ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1757ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1758ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1759ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1820aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1822b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
1823b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
1824b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
1825b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1826b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1827b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1828b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
1829b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
1830b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1831b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
1832b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1833b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
1834b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
1835b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
1836b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1837b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1838b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
1839b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
1840b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
1841b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
1842b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
1843b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
1844b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
1845b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
1846b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
1847b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1872ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1873ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1874ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1875ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1876ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
18798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
18808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
18818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
18828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
18838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
18848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
18852965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
18868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
18878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
18888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
18898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
18908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
18918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
18928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
18938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
18948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
18958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
189897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
189997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
190097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
190197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
190297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
190397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
190497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
190597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
190697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
190797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
190897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
190997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
191097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
191197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
191297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
191397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
191497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
191597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
191697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
191797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
191897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
191997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
192097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
192197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
192297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
192397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
192497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
192597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
192697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
192797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
192897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
192997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
193097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
193197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
193297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
193397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
193497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
193597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
19368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
19378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
19388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
19398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
19408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
19428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
19438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
19448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
19468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
19478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
19488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
19498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
19518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
19528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
19538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
19558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
19568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
19578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
19588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
19598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
19618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
19628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
19638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
19658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
19668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
19688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
19698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
19708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
19718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
19728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
19738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2020729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2021729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2023729de186450f78c099637e1fce743fe531862c52Andreas Huber
2024729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2025729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2026729de186450f78c099637e1fce743fe531862c52Andreas Huber
2027729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2028729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2029729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2030729de186450f78c099637e1fce743fe531862c52Andreas Huber
2031729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2036729de186450f78c099637e1fce743fe531862c52Andreas Huber
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2040729de186450f78c099637e1fce743fe531862c52Andreas Huber
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2045729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2046729de186450f78c099637e1fce743fe531862c52Andreas Huber
204717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2050729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
205117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2052729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2053729de186450f78c099637e1fce743fe531862c52Andreas Huber
20542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
20552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
20562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
20572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
20582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
20592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
20602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
20612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
20622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
20632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
20642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
20652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
20662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
20672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
20682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
20692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
20702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
20712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
20722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
20732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
20742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
20752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
20762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
20772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
20782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
20792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
20802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
20812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2082729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2083729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2084729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2085729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2086729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2087729de186450f78c099637e1fce743fe531862c52Andreas Huber
2088729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2089729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2090729de186450f78c099637e1fce743fe531862c52Andreas Huber
2091729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2092729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2093729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2094729de186450f78c099637e1fce743fe531862c52Andreas Huber
2095729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2096729de186450f78c099637e1fce743fe531862c52Andreas Huber
2097729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2098729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2099729de186450f78c099637e1fce743fe531862c52Andreas Huber
2100729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2101729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2102729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2103729de186450f78c099637e1fce743fe531862c52Andreas Huber
2104729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2105729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2106729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2107729de186450f78c099637e1fce743fe531862c52Andreas Huber
2108729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2109729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2110729de186450f78c099637e1fce743fe531862c52Andreas Huber
2111729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2112729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2113729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2114729de186450f78c099637e1fce743fe531862c52Andreas Huber
2115729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2116729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2117729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2118729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2119729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2120729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2121729de186450f78c099637e1fce743fe531862c52Andreas Huber
2122c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2123c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2124729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2125729de186450f78c099637e1fce743fe531862c52Andreas Huber
2126729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2127729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2128729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2129729de186450f78c099637e1fce743fe531862c52Andreas Huber
21305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
213197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
21325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
21335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
21345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
21355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
21365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
21375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
21385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
21395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
21405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
21415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
21425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
21435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
21445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
21455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
21465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
21475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
21485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
21495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
21505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2151f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
21540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
21550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2173229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2174229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
21750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
21760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
21770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
21780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2179229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2180229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2181229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2182229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2183229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
22230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
22240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
22250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
22260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
22270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
22280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
22290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
22300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
22310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
22320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
22330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
22340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
22350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
22360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
22370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
22420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
22430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
22460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
22470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
22480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
22490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
22500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
22510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
22520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
22530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
22540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
22550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
22560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
22570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
22590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
22600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
22620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
22630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
22650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
22660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
22670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
22680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
22690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
22700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
22710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
22730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
22740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
22750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
22760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
22770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
22780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
22790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
22800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
22810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2287e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2288e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2289e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2290e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2291e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
22922472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2293e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2294e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2295e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
229694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
229794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2298e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2299e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2302e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2303e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2304e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2305e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2306e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2307e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2308e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2311e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2312e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2313e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2314e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2315e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2316e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2317e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2318e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2319e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2322e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2323e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2324e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2325e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2326e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2327e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2328e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2329e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
23330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
233489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
233589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
233689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
233789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
233889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
233989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
235589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
235689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
235789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
235889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
23590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
236089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
236189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
236289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
23630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
236489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
236589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
23660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
236789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
237378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
237478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
237578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
237678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
237778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
237878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
237978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
238078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
238178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
238378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
24672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2472a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2473a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2474a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2475a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2476a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2546c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
2547c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
2548c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
2549c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
255089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
255189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
255289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
255389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
255489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
25650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
25660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
25670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
25680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
25700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
25720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
25730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
25740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
25750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
25760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
25770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
25780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
25790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
25810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
25820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
25830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
25840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
25850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
25860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
25870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
25890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
25900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
25910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
25920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
25930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
25940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
25950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
25960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
25970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
25980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
25990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
26000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
261196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
261296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
261396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
261496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
261596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
261696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
261796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
261896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
261996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
26205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
262796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
262896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
269296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
270896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
270996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
276896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2777a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
2778a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
2779a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
2780a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
2781a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
2782a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
2783a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
2784a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
2785a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
2786a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
2787a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
2788a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
2789a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2790a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2791a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
2792a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
2793a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
2794a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
2795a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
2796a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
2797a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2798a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
2799a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
2800a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
2801a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
2802a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
2803a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
2804a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
2805a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
2806a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
2807a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
2808a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
2809a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
2810a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
2811a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
2812a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
2813a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
2814a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
2815a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
2816a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
2817a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
2818a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
2819a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
2820a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
2821a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
2822a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
2823a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
2824a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
2825a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
2826a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
2827a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
2828a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
28295778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
28315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
283696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
283796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
28480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
28490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
28500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
28510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
28520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
28530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
28540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
28550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
28560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
28570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
28907c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
28917c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
28927c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
293496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2937c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
2938c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
2939c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
2940c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
2941c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
2942c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2943c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2944c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
2945c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2946c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
2947c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
2948c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
2949c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
2950c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2951c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2952c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
2953c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2954c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2955c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
2956c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
2957c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
2958c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2959c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
2960c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
2961c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2962c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2963c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2964c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2965c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2966c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
2967c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
2968c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
2969c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
2970c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
2971c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2972c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2973c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
2974c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
2975c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
2976c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
2977c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2978c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
2979c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
2980c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2981c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2982c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
2983c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2984c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
2985c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
2986c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
2987c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
2988c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
2989c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
2990c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
2991c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
2992c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
299389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
299489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
29954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
29964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
29974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
29984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
29994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
30004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
30014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
30024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
30034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
30044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
30054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
300689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
300789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
300889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
30094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
301089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
301189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
301289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
30134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
30144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
30154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
30164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
30174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
30184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
30204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
30214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
30224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
30234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
30244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
30254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
30264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
30274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
30284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
30294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
30304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
30314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
30324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
30334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
30344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
30354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
30374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
30384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
30394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
30404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
30414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
30424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
30434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
30444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
30454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
30464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
30474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
30484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
30504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
30514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
30524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
30534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
30544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
30554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
30564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
30584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
30594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
30604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
30624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
30634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
30644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
30654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
30664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
30674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
30684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
30694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
307089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
307189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
307289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
30735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
30745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
30755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
30765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
30775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
30785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
30825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
30835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
30855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
30915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
30925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
30945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
30955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
309996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
310096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
31015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
31025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
31035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
31045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
311396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
31145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
31225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
31235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
31375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
314778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
314878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
317678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
317778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
317878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3196d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3197d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3198d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3199d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3200d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3201d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3202d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3203d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3204d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3205d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3206d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3207d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3208d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3209d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
32107e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
32117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
32127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
32137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
32147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
32157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
32167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
32177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
32187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
32197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
32207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
32217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
32227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
32237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
32247e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
32257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
32267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
32277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
32287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3229e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
32307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3231c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3232c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
3233c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
3234c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
32357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
32367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
32377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3245609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3275229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
327603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
327703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
327803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
327903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
328003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
328103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
328203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
328303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
328403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
328503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
328603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
328703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
328803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
328903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
32905a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
32915a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
329203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3293229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
329403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
329503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3296b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3297b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3298b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3299b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3300b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3301b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3302b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3303b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3304b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3305b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3306b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3307b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3308b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3309b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
331003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
331103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
331203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
331303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
331403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
331503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
331603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
331703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
331803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
331903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
33205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
33215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
33225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
33235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
33245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
33255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
33265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
33275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
33285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
33295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
33305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
33315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
33325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
33335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
33345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
33355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
33365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
33375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
33385a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
33395a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
33405a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
33415a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
33425a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
33435a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
33445a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
334503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
334603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
334703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
334803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
334903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
335003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
335103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
335203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
335303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
335403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
335503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
335603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
335703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
335803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
335903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
336003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
336103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
336203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
336303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
336403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
336503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
336603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
336703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
336803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
336903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
337003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
337103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
337203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
337303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
337403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
337503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
337603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
337703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
337803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
337903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3380229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3381229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3382229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3383229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3384229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3385229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3386229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3387229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3388229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3389229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3390229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3391229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3392229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3393229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3394229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3395229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3396229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3397229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3398229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3399229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3400229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3401229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3402229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3403229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
34040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3405229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3406229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3407229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3408229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3409229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3410229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3411229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3412229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
34130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3414229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3415229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3416229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3417229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3418229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3419229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3420229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3421229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3422229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3423229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3424229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3425229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3426229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3427229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3428229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3429229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3430229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3431229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3432229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3433229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3434229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3435229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3436229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3437229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3438229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3439229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3440229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3441229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
344203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
344303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3444e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3445e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
344631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
344731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3448e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
344931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
345031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
345131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
345231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
345331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3454e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
3455e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
345631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
345731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
345831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
345931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
346031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3461e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3462e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3463e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3464e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3465e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3466e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3467e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3468e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3469e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3470e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
34710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
34720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
34730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
34740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
34750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
34760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
34770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
34780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
34790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
34800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
34810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
34820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
34830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
34840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
34850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
34860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
34875a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
34885a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
34895a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
34905a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
34915a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
34925a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
34935a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
34940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
349503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
349603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
349791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
349891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
349991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
350091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
350191a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
3502e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
3503e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
350491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
3505e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3506e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
350791a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
350891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
350991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
351091a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
3511e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
3512e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
3513e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
3514e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
3515e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
3516e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
351731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3518e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
3519e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
3520e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
3521e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
3522e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
3523e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
3524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3525e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
3526577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
3527577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
3528577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
3529e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
3530e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
3531e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3532e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3533e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
35344730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
35354730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
35364730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
35374730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
35384730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
35394730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
35404730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
35414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
35424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
35434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
35444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
35454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
35464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
35474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
35484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
35494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
35504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
35514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
35524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
35534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
35544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
35554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
35564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
35574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
35584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
35594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
35604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
35614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
35624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
35634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
35644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
35654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
35664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
35674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
35684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
35694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
35704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
35714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
35724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
35734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
35744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
35754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
35764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
35774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
3578e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
3579e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3580e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
3581e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
3582e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
3583e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
3584e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
3585e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
3586e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
3587e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
3588e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
359031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
3591e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
3592e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
35935a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
35945a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
35955a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
35965a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
359731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
359831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
359931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
360031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
360131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
360231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
360331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
360497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
3605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
3606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
3608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3609e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
3613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
361614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
3617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
3618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
361914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
362014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
362114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
362214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
362314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
362414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
3625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
3627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
3629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
3631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
36328b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
3633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
36348b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
36359806555d3930be43e11106281dee354820ac1c88Andreas Huber
3636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
3637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
3639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3640e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
3644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
3648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
3654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
3656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3657e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
36589806555d3930be43e11106281dee354820ac1c88Andreas Huber
3659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
3661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
3665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
3666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
3668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
3670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
3671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
3672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
3673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3674e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
3675e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
3676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
3680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
3681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
3682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
3683e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
3686e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
3687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
3688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
3689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
3691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
3692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
3693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
3694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
3695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3696e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
3697e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3698e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
3699e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3700e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3702e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3703e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
3704e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3705e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3706e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3707e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
3708e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3709e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3710e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3711e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3712e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3713e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
3714e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3715e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
3716e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
3717e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
3718e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3719e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
3720e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
3721e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
3722e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
3723e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
3725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
3726e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
3727e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
3728e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
3729e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
373097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
373197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
373297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
373397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
3734e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
373597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
373697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
373797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
373897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
373997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
374097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
374197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
374297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
374397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
374497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
374597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
374697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
3747e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
37488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
37498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
37508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
37518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
37528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
37538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
37548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    CHECK_EQ((status_t)OK, mOMX->getParameter(
37558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            mNode,
37568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
37578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            &params,
37588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                            sizeof(params)));
37598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
37608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
37618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
37628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
37638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
37648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
37658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
37668c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
37678c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
37688c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
37698c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
37708c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
37718c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
37728c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    CHECK_EQ((status_t)OK, mOMX->getParameter(
37738c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            mNode,
37748c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
37758c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            &params,
37768c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                            sizeof(params)));
37778c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
37788c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
37798c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
37808c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
37818c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
37828c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
37838c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
378410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
378510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
378610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
378710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
378810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
378910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
379010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    CHECK_EQ((status_t)OK, mOMX->getParameter(
379110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            mNode,
379210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm,
379310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            &params,
379410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                            sizeof(params)));
379510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
379610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
379710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
379810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
379910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
380010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
380110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
380210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
380310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
380410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
380510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
380610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
380710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
380810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
380941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
381041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
381141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
381241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    OMX_AUDIO_PARAM_MP3TYPE params;
381341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
381441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
381541d3f579d2c166984958263533284209b90c87d5Marco Nelissen
381641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    CHECK_EQ(mOMX->getParameter(
381741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                mNode, OMX_IndexParamAudioPcm,
381841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                                &params, sizeof(params)),
381941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                             (status_t)OK);
382041d3f579d2c166984958263533284209b90c87d5Marco Nelissen
382141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
382241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
382341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("sample-rate", params.nSampleRate);
382441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
382510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
382610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
3827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
3828e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
3829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
3830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
383131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
383231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
383331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
383431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
383531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
383631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
383731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3838e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
3839e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
3840e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
38424e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
3843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
3844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
3846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
3848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
3849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3850e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
3851e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
3852e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
3853e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
3854e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
3855e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
3856e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
3857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
3858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
3859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
3860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
3861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
3862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
3863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
3864e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
3865e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
3866e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
3867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
3868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
3869e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
3870e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
3871e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
3872e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
3873e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
3874e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
387531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
387631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
387731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
387831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
387931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
38805778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
3881cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
3882d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
3883251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
3884251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
3885251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
3886251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
3887251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
3888251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
3889251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
3890251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
3891251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
3892251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
38935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
3894251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
3895cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
3896cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
3897cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
3898bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
3899bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
3900bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
3901bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
3902bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
3903bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3904bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
3905bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
3906bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
3907bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
3908bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
3909bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3910bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
3911bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3912bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3913bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3914bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3915bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
3916bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
3917bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3918bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3919bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3920bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
3921bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3922bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3923bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
3924bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
3925bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3926bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
3927bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3928bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3929bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3930bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
393187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
393287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
393387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
393487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
393587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
393687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
3937bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3938bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3939bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
3940bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
3941bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3942bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
3943bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3944bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3945bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3946bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3947bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
3948bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
3949bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3950bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
3951bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
3952bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3953bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3954bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3955bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
3956bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
3957bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
3958bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
3959bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
3960bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
3961bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3962bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3963bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
3964bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
3965bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
3966bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
3967bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
39681e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
3969bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3970bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
3971bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3972bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3973bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3974bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3975bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
3976bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3977bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
3978bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
3979bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
3980bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3981bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
3982bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3983bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3984bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3985bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3986bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
3987bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3988bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
3989bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3990bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
3991bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3992bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
3993bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3994bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3995bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
39961e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
3997bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
3998bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
3999bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4000bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
4001bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4002bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4003bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
4004bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4005bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4006bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
4007bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4008bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
4009bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
4010bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
40111e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
4012bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4013bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4014bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
4015bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4016bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
4017bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4018bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4019bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
4020bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
4021bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
4022bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
4023bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
4024bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4025bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
4026bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4027bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4028bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4029bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4030bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
4031bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
4032bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
4033bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
4034bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
4035bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
4036bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4037bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4038bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
4039bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
4040bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
4041bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4044eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4045eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4046eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4047496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4048496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4049496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4050496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4051496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4052496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4053496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4054496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4055496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4056496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4057496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4058496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4059496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4060496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4061496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4062496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4063496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4064496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4065eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4066eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4067eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4068eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4069eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4070eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4071eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4072eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4073eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4074eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4075eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4076eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4077eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4078eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4079eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4080eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4081eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4082eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4083eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4084eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4085f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4090ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4091ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
41157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
41167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4117251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
41187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
41197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
41207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
41217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
41227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4123ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4124ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4126ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4127ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4128ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4129ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4130ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
413130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
413230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
413330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
413430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
413530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
413630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
413730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
413830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
413930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
414030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
414130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
414230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
414330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41555e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
41565e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
41575e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
41585e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
41595e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
41605e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
41615e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
41625e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4164609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41750af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
41760af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
41770af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
41780af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
41790af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
41800af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
41810af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
41820af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
41830af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
41840af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
41850af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4195609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4203609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
4217784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung                    timeUs);
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
42293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
423529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4237251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4238251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4239251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4240251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4241251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4242251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4243251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
42493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
4250349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4251349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
425896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
425996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
426096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
426196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
426296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
426396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4264d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4294d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4295609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
42982d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
4301609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4312609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
43132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
43155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4316a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
43175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43182d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4319a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
43237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
43247fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
43257fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
43267fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
43277fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
43287fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
43297fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
43303831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
43312d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
43355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
43365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
43375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
43385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
43485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4349dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4350dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4351dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4352dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
43595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
43715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
43725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
43735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
4376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4384078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
43853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
4386078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
43875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
43885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
43895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4390078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4391d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4392d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
4393d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4394d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
43953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
4396078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
4397d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4398078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4399349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4400d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4407054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
4408054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4409054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4410054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4411054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
4412054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
4413054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4414054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4415054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4416e53350373ac516257b4f8956ff1e3f1ac48f607eLajos Molnar                        mCodec->submitOutputMetaDataBuffer();
4417054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4418054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
4419054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
44325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
44335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
44345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
44355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
44365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
44385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
44395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
4441dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
44423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
4443dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
4444dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4445dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
44463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4447dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4448dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
4451349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4452349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4465dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4469625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4470625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4471625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4472625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
4509784e24e386b088c05d653ab482f2e95cb53e3d01Andy Hung        int64_t timeUs) {
4510609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
45115778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
4512349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
4517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
4518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
4519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
4520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
4522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
4523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
4524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
4526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
4527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
4528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4535054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4546a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
4547a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
4548609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
45495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
4550349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
45515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
45525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
45535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
45565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
45575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
455831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4559577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
4560577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
4561577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
45624bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
4563577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
45645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4566308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
4567308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
4568308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
4569308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
4570308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
4571308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
4572308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
4573308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
4574308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
4575496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
457621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
4577496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
4578496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
4579496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
45805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
458121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
45848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
45858b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
45865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4589d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
4590609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
45912d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
45925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4594609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
45995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
46035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
46045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
4606d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
4607dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4630609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4636577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
4637577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
4638577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
4639577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
4640577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
4641577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
4642577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
46456aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
464679ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
46476fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4650fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
4651fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
4652fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
4653fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
4654fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
4655fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
4656fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
4657fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
465847aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
4659fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
4660fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
4661fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
4662fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4663fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
46645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
4665fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
4666fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (err != OK) {
4667fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            ALOGW("failed to set buffer timestamp: %d", err);
4668fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
4669fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
46705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
46721e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
4673cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
4674cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
4675251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
4676cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
4677cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
46796fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
46806fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
46816fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
46826fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4712c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
4713609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
4714c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
4715349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4716c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4717c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4719c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4720c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4738f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4742c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
4743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
4744ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4745ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
4746f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
4747ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4748ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4749ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4750ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
4751ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
4752ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
4753ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
4754ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
4755308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
4756ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
4757c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4758c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
47725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
47735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
47745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
47755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
47765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
47775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4780c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
478354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
478454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
4785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4787d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4791c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4797d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4801c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
480430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
480530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
480630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
480730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
480830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
480930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
481030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
4821c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
4822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
4823c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
48245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
48255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4826c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
48275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
48285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
48305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4836ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
4837ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4838ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
4839f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
4840ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
4841ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
4842ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
4843ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
4844ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
4845e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
48465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
4850d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
48517791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
48525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
4853e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
4854e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
4855e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
4856afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
4857e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
4858e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
4859e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
4860afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
48615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
48625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
48635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
48655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
48665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
48675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
48695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
48705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
48715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
48725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
4873e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
48745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
48751065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
48761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
48771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
48781065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
48791065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
48801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
4881e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
4882e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4884da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
4885078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
4886078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
48871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
4888078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48901065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
48911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
48927a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
48937a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
48941065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
48951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
48961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
48971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
48981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4899c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
49005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
49017791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate a %scoder for type '%s'.",
49027791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen                    encoder ? "en" : "de", mime.c_str());
49035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
49047791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen            ALOGE("Unable to instantiate codec '%s'.", componentName.c_str());
49055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4906c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
4907cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
4908c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
4909c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4911ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
4915ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
4916ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4917ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
4918ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
49191713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
49200167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
4921ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
4922ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4923afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
4924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
4925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
49285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4929d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
49305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
49315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
49325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4933c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4934c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
4935c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4936c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
49375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
49385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4939c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
4940c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4941c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
4942c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
4943c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4944c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4945c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
4946c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
4947c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4948f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
4949f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
4950f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4951f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
4952f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
4953054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
4954054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
4955a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
4956e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
4957e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
49584e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
4959054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4960c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
4961c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
4962c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4963c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
4964c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
4965c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4966c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
4967c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
496854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
4969f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
4970f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
4971c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4972c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4973c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
4974c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
4975c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
4976c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4977c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
4978c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
4979c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
498054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
498154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
4982d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
498354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
498454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
498554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
4986c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
4987c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4988c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
4989c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
4990c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4991c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
4992c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
4993c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
4994c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
4995c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
4996c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
4997c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
4998c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
49997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
50007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
50017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
50027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
50037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
50047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
50057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5007c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5008c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5009c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5010c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5011c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5012c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5013c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5014c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5015c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5016c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5017c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5018c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
501954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5020c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5021c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5022c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5023c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5024c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5025c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5026c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5028c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5029d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5030c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5031c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5032c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5033c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5034c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5035c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5036c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5038c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5040c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5041c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5042c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5043c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
50445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
50455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
50465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
50485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
50505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
50515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
50535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5055c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5056c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5057c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5058251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5059c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
50605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
50635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5064d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5065e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5066e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
50675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
50685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5070c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
50715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
50725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
5074ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
50757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
50767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
50777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
5078d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
50797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
50807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
50817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
50827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
50837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
50847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
5085a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5086a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
5087a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5088a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5089a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5090a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5091a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5092a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5093a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5094a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5095a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5096a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5097a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5098a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5099a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5100a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5101a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
51022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
510394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
510494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
510594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
510694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
510794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
510894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
510994ee4b708acfa941581160b267afb79192b1d816Chong Zhang
511094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
511194ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
511272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
511372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
51142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
51152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
51162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
51172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
51182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
51192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
51202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
51212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
51222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
51232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
51242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
51252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
51262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
51272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
51282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
51292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
51302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
51312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
51322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
51332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
51342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
513572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
513672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
513772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
513872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
513972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
514072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
514172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
514272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
514372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
514472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
514572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
514672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
514794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
514894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
514994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
515094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
515194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
51527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
51537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
51547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
51557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
51567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
51577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
51587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
51597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
51607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
51617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
51627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
51637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
51647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
51657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5166c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
51675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
51685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
51705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
5172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
5174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5178f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5182f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
51833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5185cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5186cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
518729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5188cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5189cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5190cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5191251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
519291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
519391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5194cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5207f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
520972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
52176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
52186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
52196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
52206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
52216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
52226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
52236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
52246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
52256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
52266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
52276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
52286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
52296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
52306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
52316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5232d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
52336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
52346463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
52356463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
52366463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
5252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
5255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5266f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
52713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
527672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5283d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5284d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5285d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5286d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5287d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5288d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5289d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5290d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5291d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5292d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5293d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5294d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5295d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5296d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5297d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5298d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
52996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
53006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
53016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
53026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
53036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
53046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5310f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5331f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5333349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5336f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5337ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5341054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5342054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5343054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5344054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5345054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5346054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5347054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5348054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
5349054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5350054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5351054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
53524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
53534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
53544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
5355054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5356054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5357054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
5373349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
5374349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5382054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
5383c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
5384054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
5385054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
5386054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
5387054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
5388054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
5390349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
53913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
5392349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
5393349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5394349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
5395349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
5396349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53993cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
5400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
54013cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
54023cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
54033cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
54043cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
54053cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
54063cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
5407349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5408349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5411f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
54123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
5415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5423c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5424c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5425c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5426c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
542854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
5430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5431349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5432349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
5435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
54457a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
5446d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
5447d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
5448d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
5449d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
5450d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
5451d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
5452d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5453349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
5454349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5472496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
5473496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
5474496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
5475496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
5476496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
5477496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
5478496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5479496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
5480496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
5481496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
5482496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5483a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
5484a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
5485a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
5486a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
5487a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5488a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
5489a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5490a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
5491a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
5492a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
5493a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
5494a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
5495a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5496a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
5497a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
5498a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5499a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
55007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
55017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
55026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
55037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
55047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
55057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
55067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
55074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
55084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
55094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
55104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
55114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
55124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
55134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
55144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
55154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
55164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
55174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
55184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
55194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5528a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
5529a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
5530530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
5531a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
5532a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
5533a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
5534a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
5535a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5536a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
5537a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
5538a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
5539a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
5540a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
5541a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5542a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
5543a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
5544a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
5545a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5546a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
5547a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
5548a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
5549a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
555072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
555172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
555272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
555372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
555472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
555572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
555672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
555772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
555872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
555972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
556072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
556172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
556272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
556372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
556472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
556572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5566e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
5567e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
5568e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
5569e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5570b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
5571b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
5572e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
5573e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
5574e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
5575e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
5576b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
5577b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5578b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5579b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
5580b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5581b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5582b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
5583b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5584b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
5585b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
5586b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
5587b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
5588b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
5589b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
5590b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
5591b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
5592e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
5593e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
5594a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
5595a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
5596a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
55976507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
55986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
5599d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
56006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
56016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
56026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
56036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
56046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
56056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
56066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
56076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
561531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
5616054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
5619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
5620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5622349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
5623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
562531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
562631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
56283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5647f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
5649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5652f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5670349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
5671e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5673349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
56743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
5675349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
5676349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5690f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
56913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
5692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
5701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
5704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
5707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
5710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
5711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
5712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5713cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
5714cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
5715cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
571629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
5717cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
5718cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
5719cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5720251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5721d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5722755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
5723755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
5724755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
5725755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
5726755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
5727755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
5728755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
5729755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
5730cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
5731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
5734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
5735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
573631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
573731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
57383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
5739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
5740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5741349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
5742349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
5743349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
5744349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
5748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5760f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
57615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
57625778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5793f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
57943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
579531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
57965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
579731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
5798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5800f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
5807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
58095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5815349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5816349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
5817349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5818349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
5819349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
5820349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
5821349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
58260af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
58285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
5829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
5830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
5831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
5832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
5834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
5835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58360167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
58370167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
5838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
5839bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
5840bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
5841bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
5842bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
5843bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
5844bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
5846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5849f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
5850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
5852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
5857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
5859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
5861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5865f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
58983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
5899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
5907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5909c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5921f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
59263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5931f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
5942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
5944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
5957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
59587a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
5959d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
5960d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
5961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
5965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
5967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
5968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
5969e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
5970e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
5971e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
5972e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
5973e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
5974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
5975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5985349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
5986349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
5987349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
5988349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
5989609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
5990349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
5991349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
5992349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
5993349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
59943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
5995349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
5996349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5997349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
5998349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5999349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6000349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6001349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
60257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
60267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
60277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
60287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6030d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6036dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6037dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6038f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6039f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6040f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6041f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6047